-
Notifications
You must be signed in to change notification settings - Fork 441
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
从vue-cli源码学习如何写模板 #56
Comments
学习了,感谢分享 |
谢谢分享,根据您的分享,我自己也成功搭建了一个属于自己的vue模板。 |
请问大佬一个问题,我写的针对业务的模版中有vue变量({{obj.name}}这种形式)在html中,但是初始化之后的代码中,貌似被当作 handlebars 的 mustaches 表达式,因为找不到对应的变量就直接被忽略了,请问有什么办法能阻止这种问题吗?我目前的想法是给handlebars的变量替换加个范围,然后让某些文件中的mustaches写法的不受影响,但是找不到如何下手,求大佬指点一下 |
@fundatou 把 |
@dwqs 这样是可以的,谢谢大佬! |
如果模版想部署在 私有 gitlab 库 并且想用 vue cli 应该从哪些地方入手 |
vue cli 貌似并不支持,你可以改下源码 哈哈 @choukin |
我觉得好像可以诶,按照vue cli中用的download-git-repo的源码写正确的初始化命令就行了吧 @choukin ,不知道你是不是想问这个问题 |
@fundatou 多谢我试试 |
博主你好,我一直无法理解 ,我已经fork vue的webpack,然后在template中/src/components/增加了一个Hi.vue文件,但是使用命令 vue init xxxxx/my-webpack my-project 生成的项目里面,为什么还是只有HelloWord.vue? |
我也有这个需求,请问下朋友解决了吗? |
download |
vue-cli
是 vuejs 官方提供的基于 vuejs 的项目脚手架工具, 可以很快的帮助 vuejs 开发者搭建一个 startup 项目, 免去环境配置的繁琐, 开箱即用. 今天就来看下vue-cli
的实现.vue-init
vue init
是基于第三方模板生成项目的命令. 先看下其整体流程:首先,
vue cli
获取到输入的参数:之后, 会先判断用户是否输入了
offline
选项. 如果有, 则会使用之前缓存的模板:如果没有, 则判断将会生成的项目目录是否存在. 若存在, 则会向用户确认是否在当前目录生成项目(代码在这); 若不存在, 之后就会生成一个新的目录.
然后, 会去判断使用的模板是否是本地的, 是本地且存在则使用本地模板生成项目, 反之使用线上模板生成项目(代码在这).
在判断是使用线上的模板之后, 会根据模板名是否带
/
判断是使用官方提供的模板还是使用第三方模板(代码在这).最后会调用
downloadAndGenerate
去下载官方模板或第三方模板来生成项目(代码在这).vue cli
对模板的下载依赖于 download-git-repo, 所以使用第三方模板时, 对指定模板的输入要求可以见download
.模板下载成功之后,
vue cli
会调用generate
来生成模板, 这是 cli 的核心模块, 其源码在lib/generate.js
中. 接下来就具体分析generate
模块.generate
模块导出之前, 会先在handlebars
中注册两个辅助函数:if_eq
和unless_eq
, 用于模板中的表达式判断:导出的
generate
函数接收四个参数: 项目目录名、下载的模板的临时路径、项目目录路径和一个回调函数. 回调函数用于项目生成之后在终端输出一些提示信息. 在generate
函数内, 首先会读取模板的meta
信息, 读取的meta
信息来自于模板目录下的meta.{js,json}
文件:具体实现戳此. 之后会读取用户的 git 昵称和邮箱用于设置
meta
信息的一些默认属性.得到基本的
meta
信息之后, 会利用 metalsmith 读取template
内容:需要注意的是, 读取的内容是模板的
tempalte
目录. metalsmith 会返回文件路径和文件内容相映射的对象, 这样会方便 metalsmith 的中间件对文件进行处理.之后,
vue cli
使用了三个中间件来处理模板:askQuestions
中间件
askQuestions
用于读取用户输入:ask
的源码在vue-cli/lib/ask.js
中, 其会遍历prompts
, 在终端交互式的读取用户输入, 并将数据保存在global metadata
中, 便于后续依赖global metadata
的中间件对模板进行进一步处理.prompts
是一个对象, 每个prompt
都是一个 Inquirer.js question object. 示例如下:在
ask
中, 对meta
信息中的prompt
会有条件的咨询用户:经过
askQuestions
中间件处理之后,global metadata
是一个以 prompt 中的 key 为 key, 用户的输入为 value 的对象:filterFiles
中间件
filterFiles
会根据meta
信息中的filters
都文件进行过滤:filter
的源码在vue-cli/lib/filter.js
中:evaluate
用于执行 js 表达式, 关键定义如下:所以在
filters
中, 可以将某些key
的value
定义为一个 js 表达式.renderTemplateFiles
根据用户的输入过滤掉不需要的文件之后, 就可以利用
renderTemplateFiles
中间件来渲染模板了:渲染完成之后, metalsmith 会将最终结果 build 的
dest
目录. 若失败, 则将err
传给回调输出; 反之, 如果meta
信息有complete
(函数) 或者completeMessage
(字符串), 则会进行调用或输出:vue-list
vue list
命令用于查看官方提供的模板列表, 源码在vue-cli/bin/vue-list
中, 关键代码如下:需要注意的是, Github Api 对未认证的请求是有请求数限制的, 超过限制则会报错, 但可以通过 BA 认证的方式来提高请求数限制, 具体可以戳此.
这是个潜在的问题, 已经有
vue-cli
的用户碰到过认证失败的问题: #368.vue-cli
的下一个版本可能会解决这个问题, 已经有社区用户提出 PR.怎么自己写模板呢
从上述的分析可以知道, 模板是有特定的目录结构的:
template
目录, 在该目录下定义你的模板文件meta.{js,json}
文件, 该文件必须导出为一个对象, 用于定义模板的meta
信息对于
meta.{js,json}
文件, 目前可定义的字段如下:prompts<Object>
: 收集用户自定义数据filters<Object>
: 根据条件过滤文件completeMessage<String>
: 模板渲染完成后给予的提示信息, 支持 handlebars 的 mustaches 表达式complete<Function>
: 模板渲染完成后的回调函数, 优先于completeMessage
helpers<Object>
: 自定义的 Handlebars 辅助函数prompts
prompts
是一个对象, 每个prompt
都是一个 Inquirer.js question object. 示例如下:所有的用户输入完成之后,
template
目录下的所有文件将会用 Handlebars 进行渲染. 用户输入的数据会作为模板渲染时的使用数据:在上述示例中, 只有用户在
test
中的回答值是yes
时,test
脚本才会在package.json
文件中生成.prompt
可以添加一个when
字段, 该字段表示此prompt
会根据when
的值来判断是否出现在终端提示用户进行输入. 在vue-cli
中, 其会根据when
进行eval
运算:带
when
的prompt
示例:在上述示例中, 只有用户在
lint
中的回答值是yes
时,eslint
才会被触发, 在终端显示让用户选择eslint
的配置规范.filters
filters
字段是一个包含文件过滤规则的对象, 键用于定义符合 minimatch glob pattern 规则的过滤器, 键值是prompts
中用户的输入值或者表达式. 例如:在上述示例中,
template
目录下test
目录只有用户在unit
中的回答值是yes
时才会生成, 反之会被删除.如果要匹配以
.
开头的文件, 则需要将 minimatch 的dot
选项设置成true
.helpers
helpers
字段是一个包含自定义的 Handlebars 辅助函数的对象, 自定义的函数可以在template
中使用:在
template
的文件使用该if_or
:complete
在渲染完成后的
complete
回调:data
和helpers
由vue cli
传入:如果
complete
有定义, 则调用complete
, 反之会输出completeMessage
.总结
vue-cli
的源码还是很好分析的, 参考vue-cli
, 写了一个简化的脚手架工具chare
, 其新加了三个功能:自己针对日常使用的
vuejs
和react
框架写了一些 startup, 欢迎指正:The text was updated successfully, but these errors were encountered: