最近时间充裕,手写了下 vue-router 和双向绑定,现在借着上一篇的内容。
vue-cli-service
当脚手架帮我们创建好文件的基本结构后,接下来就是 vue-cli-service 命令了。
- vue-cli-service serve // 本地服务 webpack-dev-server
- vue-cli-service build // 打包构建
- vue-cli-service lint // 语法检查
归根而言就是一个命令,三个参数,不多废话,正式开始。
这个 vue-cli-service.js 只是解析下参数。
const Service = require('../lib/Service')
const service = new Service(process.env.VUE_CLI_CONTEXT || process.cwd())
service.run(command, args, rawArgv).catch(err => {})
Service.run
async run (name, args = {}, rawArgv = []) {
// mode 就是 production, development,test 之类的。const mode = args.mode || (name === 'build' && args.watch ? 'development' : this.modes[name])
this.init(mode)
// name 为 build, serve, lint
// fn 就是执行对应的命令
let command = this.commands[name]
const {fn} = command
return fn(args, rawArgv)
}
run 里面调用了 this.init(mode),init 里面会去获取用户的配置文件,即 vue.config.js,或者 package.json 里面的 vue 字段。具体代码就不贴了,很简单。
init 里面同样会去注册 commands 里的命令, 里面其实绕来绕去,但最后调用的是 commands 目录下的各个命令文件。
vue-cli-service serve
这章重点讲下 serve 这个命令, 但其实就是一个 webpack-dev-server 的配置,不过脚手架走的是 api 调用。
直接找到 new WebpackDevServer。第一个参数 compiler,这个是 webpack 参数,第二个参数 webpack-dev-server 参数. 这个可以看官方文档,webpack 参数和 build 命令一起讲
webpack-dev-server 的配置就不多讲了,详细可以看文档。
vue-cli-service inspect
这个命令就不多讲,只讲下当我们 inspect 后,能够输出一份配置文件,也就是 vue 脚手架所用的 webpakc 配置文件。
接下来我们一个字段一个字段来详解一下这份配置文件。我没有做任何额外的配置,都是脚手架默认配置。
- entry 这个就简单了, 入口文件就一个 main.js, 自己写的时候也可以把垫片库写进去,如 @babel/pollify
- mode, context,devtool
- output
- resolve
- module,这个配置比较繁琐,有很多重复配置,如支持.scss,sass,less,css,其实都是差不多,我会选择性省略
静态资源,如 jpg 图片,svg,mp4 媒体文件等,字体文件,都的都是 url-loader 和 file-loader。
url-loader,可以把小文件转成 base64,减少 http 请求
file-loader,解析资源路径,并拷贝到输出目录css 只讲 scss 配置,vue-cli 支持 css 模块化,所以 scss 写了两种配置。
普通的 scss 配置
很简单配置,可以理解为先 sass-loader 识别解析 sass,postcss-loader 加前缀,支持新语法,css-loader 解析成 css,因为是 production 环境,所以用了 min-css-extract-loader,提取成独立的 css 文件,如果是开发环境就是 style-loader,直接插入到页面中,方便调试
css 模块化
配置上就是 css-loader 有差别,因为上家公司开发 react,一直用的是 css 模块化,这家公司用的是 scope, 个人感觉 css 模块化开发虽然写法上繁琐了些,但是打包出来的 css 是真正做到隔离了,css 名字是一个 hash 值,而 scope 会导致 html 有多余属性。
css 模块化写法,会把所有的样式都当初一个对象的属性,如 style.title,那么在模板里面就要写成 class=”style.title” 的格式