在本章当中,我们不使用官方提供的 Vue-Cli
,而是从头开始搭建,一步一步实现一个简易脚手架,理解 Vue-Cli
到底是怎么实现的(顺路了解一下 Webpack
在 Vue
项目中的使用)
源码可以见 基于 vue-cli 整合的一个个人脚手架
需要注意的是,
Webpack
和Vue
的版本均在2.0
以上
创建目录
大致目录结构如下
1 | ├── index.html ==> 根本件,最后用于展示 App.vue 组件 |
首先新建一个 HTML
文件,添加一个 id
为 box
的容器
1 | // html |
然后在 main.js
文件中添加一点内容,用于最后的渲染
1 | // main.js |
接下来来安装 Webpack
和 webpack-dev-server
,再配置一下 Webpack
,先简单的指定一下入口和出口文件
1 | // webpack.config.js |
然后就可以在我们的 index.html
中引入出口文件中指定的 JavaScript
- 这里是
bundle.js
,但是目录中不使用webpack -p
的话是不存在这个文件的 Webpack
会在编译执行的时候为我们自动生成该文件
1 | // index.html |
关于出口文件,如果想指定输出的目录,可以按照下面这样来设置
1 | output: { |
配置 vue-loader
如果需要解析像 App.vue
这样的文件,使其变成正常可以访问的代码,我们需要引入 vue-loader
来处理,这个时候我们就可以在 Webpack
中配置我们的相关 loader
了(这也是 Webpack
最核心的东西),在 webpack.config.js
中添加
1 | module: { |
配置完 Webpack
以后就可以来安装 vue-loader
以及其相关的一些组件了,单单使用 vue-loader
编译写入 .vue
文件是不够的,因为在 .vue
文件当中主要分为三大块,如下所示
1 | <template></template> |
每一部分都需要相对应的 loader
来进行处理,这时就需要同时安装以下 loader
1 | // 处理模版 |
可以使用以下命令来进行安装
1 | npm install vue-template-compiler css-loader vue-style-loader vue-hot-reload-api --save-dev |
配置 babel
众所周知,现在浏览器对 ES6
语法的支持还不是很完善,这个时候也就需要使用 Babel
来解析 ES6
语法,先来配置 Webpack
1 | module: { |
Babel
需要的相关组件如下
1 | babel-loader ==> 主程序 |
最后来汇总一下所有涉及到的依赖
1 | vue-loader ==> 编译写入 .vue 文件 |
启动
安装和配置完成以后,这个时候就可以来启动程序了,但是如果想在命令行直接使用类似 npm run dev
命令的话,就需要配置一下 package.json
文件,在 scripts
标签下设置
1 | // 设置 scripts 即可 |
然后就可以使用 npm run dev
命令来启动服务了,如果在控制台中看到
1 | Project is running at http://localhost:8080/ |
这个时候就表明启动成功了,可以访问 http://localhost:8080/
来查看效果了,如果配置全部正确的话,就可以在浏览器中看到对应的内容了,修改内容直接保存,浏览器也会自动跟着刷新,如果在最后运行的时候发现控制台出现如下内容
1 | [Vue warn]: You are using the runtime-only build of Vue where the template compiler is not available. |
这个就主要涉及到了 Vue
的运行时构建和独立构建的区别,简单来说,就是在独立构建的时候可以使用用 template
选项,而在运行时构建则不行,只能通过模板来编译转成 render
函数,两者区别如下
- 独立构建包含模板编译器,运行时构建不包含模板编译器
- 模板编译器的作用就是将
template
选项编译成render
函数,render
函数是渲染的关键 - 鉴于以上两点,使用运行时构建时,不能出现
template
选项- 因为此时没有模板编译器,但是有一种情况除外,即
webpack + vue-loader
情况下单文件组件中出现template
是可以的
- 因为此时没有模板编译器,但是有一种情况除外,即
- 使用
Vue-Cli
生成项目时,会提醒使用哪种构建方式,npm
包默认导出的是运行时构建- 如果需要使用独立构建,需要在
Webpack
中配置alias
- 如果需要使用独立构建,需要在
目前暂时发现的两者的应用场景上的区别有
- 需要注意
Vue
实例化时的方式,运行时构建方式下实例化Vue
时,不要出现template
属性 index.html
中不要出现template
或者是通过vue-router
渲染的route-view
- 以上区别讨论的场景均为使用
webpack + vue-loader
单文件组件下
解决办法也很简单,只需在 Webpack
配置中设置一下 Vue
的别名即可
1 | resolve: { |
h => h(App)
在 vuejs
中,可以把 h
函数仅是作为 createElement
函数的缩写,所以上述代码可以理解为
1 | render: function (createElement){ |
render
方法
1 | render: function (createElement) { |
也是 2.0
新增的函数,可以直接给绑定节点渲染一个 Vue
组件,如果在 1.x
的版本下,就应该使用
1 | new Vue({ |
.babelrc
和 .bowerrc
是一样的原理,都是用来配置文件,只需要在根目录新建一个名为 .babelrc
文件,然后添加
1 | { |
就可以达到和上面一样的效果
url-loader
url-loader
是对 file-loader
的上层封装,比如可以在 Webpack
中对图片的加载器进行配置
1 | { |
这样一来,在小于 8K
的图片将直接以 base64
的形式内联在代码中,可以减少一次 HTTP
请求,所以在处理一般小图片的时候就可以使用 url-loader
来转为 base64
,其他情况照常使用 file-loader
webpack 中的 loader 和 plugin
Webpack
是一个模块打包器(module bundler
),提供了一个核心,核心提供了很多开箱即用的功能,同时它可以用 loader
和 plugin
来扩展,Webpack
常用配置包括 devtool
、entry
、output
、module
、resolve
、plugins
、externals
等,这里我们主要介绍 Webpack
常用的 loader
和 plugin
Webpack
允许我们使用 loader
来处理文件,loader
是一个导出为 function
的 Node.js
模块,可以将匹配到的文件进行一次转换,同时 loader
可以链式传递
使用方式
一般 loader
的使用方式分为三种,第一种,在 webpack.config.js
中配置(较多)
1 | module.exports = { |
第二种,通过命令行参数方式
1 | webpack --module-bind 'txt=raw-loader' |
第三种,通过内联使用
1 | import txt from 'raw-loader!./file.txt'; |
一些比较常用的 loader
- 样式有
style-loader
、css-loader
、less-loader
、sass-loader
等 - 文件有
raw-loader
、file-loader
、url-loader
等 - 编译有
babel-loader
、coffee-loader
、ts-loader
等 - 校验测试有
mocha-loader
、jshint-loader
、eslint-loader
等
比如下面配置,可以匹配 .scss
的文件,分别经过 sass-loader
、css-loader
、style-loader
的处理
1 | module.exports = { |
style-loader
,将创建一个style
标签将CSS
文件嵌入到HTML
中css-loader
,处理其中的@import
和url()
sass-loader
,转化sass
为CSS
文件,并且包一层module.exports
成为一个js module
其他一些相关 loader 介绍
vue-loader
、coffee-loader
、babel-loader
- 等可以将特定文件格式转成
JavaScript
模块 - 将其他语言转化为
JavaScript
语言和编译下一代JavaScript
语言(ES6
)
- 等可以将特定文件格式转成
file-loader
、url-loader
- 可以处理(静态)资源
file-loader
- 可以复制和放置资源位置,并可以指定文件名模板,用
Hash
命名更好利用缓存
- 可以复制和放置资源位置,并可以指定文件名模板,用
url-loader
- 可以将小于配置
limit
大小的文件转换成内敛data url
的方式,减少请求
- 可以将小于配置
raw-loader
- 可以将文件以字符串的形式返回
imports-loader
、exports-loader
- 等可以向模块注入变量或者提供导出模块功能,常见场景是
jQuery
插件注入$
,imports-loader?$=jQuery
- 禁用
AMD
,imports-loader?define=false
- 等同于
var $ = require('jQuery')
和var define = false;
- 等可以向模块注入变量或者提供导出模块功能,常见场景是
expose-loader
- 暴露对象为全局变量