译文地址
Vue.js build set-up from scratch with webpack, vue-loader and hot reload
Vue.JS 是我现在最喜欢的JavaScript视图库,在这篇文章中,我将向你解释如何使用Vue.JS、热模块修改、webpack以及整个vue生态系统建立一个项目,这样你就能更好的理解你的应用是如何工作的了。
从2007年至今,我已经使用JavaScript开发了很长时间,我喜欢angular,我喜欢react和ember,我能看到这些框架背后的动机和辉煌,但真正让我感到兴奋的框架是VueJS,他不是解决所有问题的完美方案,但我(以及很多人)看到了其中蕴含的价值。
在JavaScript中有一个整体趋势,尤其在react社区,让库专注于做好一件事,并允许用户将各种碎片以最好的方式粘在一起。这种方式很棒并且为大量的人服务,这对于初学者来说有一点压迫性。我受到了这篇文章的启发写下了这个教程,有大量的react模板在这-有些是过时的,有些有问题,而有些则无法工作,这些对于初学者而言都是痛苦的。
在写这篇文章的时候,Vue的开发者正在开发”官方入门套件”,其中包含一个脚手架CLI来帮助构建一个新工程。这为开发带来了一个简单清晰而又可良好维护的出发点。
当然,搭建一个你自己的开发环境仍有很多好处:
- 对比使用模板,你自己的工程依赖会更加顺手。
- 如果有依赖不可用或你想要一些更新的东西,比如依赖一个预处理器或工具链,你可以直接将他引入而不会破坏构建流程。
- 模板也许使用了某些你不需要的东西或库。
也就是说,模板和脚手架,尤其是那些发布的作者会更加了解库的价值,而你可以利用他们来学习并了解其原理,在你学习源码之后你就可以选择使用他们的模板。
请注意,在我写作的同时我也在不断学习一些新的东西,这篇文章我会经常更新。
我最后修改这些说明是在2015年12月28日,我已经在Ubuntu Linux上使用最新的稳定版Node.js(5.3)测试过。
在命令行运行命令如下所列
$ ls <- Run this in root directory of our project
$ (public/) ls <- Run this in the 'public' directory
让我们从一个空的文件夹开始建立一个名为”myapp”的工程,这将是未来所有说明的root文件夹
$ mkdir myapp
$ cd myapp/
在root文件夹建立一个package.json
,至此我们还没有依赖。
{
"name": "myapp",
"version": "0.0.1",
"description": "My app",
"dependencies": {
},
"devDependencies": {
},
"author": "You"
}
在root文件夹建立一个index.html
,这将是提供给浏览器的实际html。
<html lang="en">
<head>
<meta charset="utf-8">
<title>Vue Exampletitle>
head>
<body>
<h3>{{ message }}h3>
<script src="dist/build.js">script>
body>
html>
注意关于这个html文件的两件事:
1. 它使用了dist/build.js
,而这一个JS文件还没有创建
2. 他有一个{{ message }}
片段,其数据将由vue在稍后填充
建立一个文件夹src
并增加一个文件src/main.js
:
import Vue from 'vue'
new Vue({
el: 'body',
data: {
message: "Hello Vue"
}
})
至此我们已经有了基础vuejs应用的骨架,但他还需要构建完成。
在你的root文件夹下新建一个文件名为webpack.config.js
,在其中填充代码:
module.exports = {
// 这是包含其他模块的主文件
entry: './src/main.js',
// 编译好的文件应该放哪?
output: {
// 路径在dist文件夹下
path: './dist',
// 文件名为`build.js`,因此完整的路径为dist/build.js
filename: 'build.js'
},
module: {
// 特殊编译规则
loaders: [
{
// 请求webpack检查:如果文件以.js结尾,则应用转换
test: /\.js$/,
// 使用babel进行转换
loader: 'babel',
// 不转换node_modules文件夹(不需要编译)
exclude: /node_modules/
}
]
}
}
在你的root文件夹下新建一个文件.babelrc
,Babel是用于转换ES6到当前JavaScript版本的工具,它需要用presets配置,Vue依赖es2015
preset(支持下一代EcmaScript/JavaScript)和stage-0
(我不知道这是干嘛的[译者注:stage-0
为ES7不同阶段语法提案的转码规则,此为第一阶段])
{
"presets": ["es2015", "stage-0"],
"plugins": ["transform-runtime"]
}
安装webpack命令行工具:
$ npm install -g webpack
安装本地库需要构建(如dev dependencies,开发依赖),我们可以将他增加到你的package.json的devDependencies
部分。
"babel-core": "^6.1.2",
"babel-loader": "^6.1.0",
"babel-plugin-transform-runtime": "^6.1.2",
"babel-preset-es2015": "^6.1.2",
"babel-preset-stage-0": "^6.1.2",
"babel-runtime": "^5.8.0",
"webpack": "^1.12.2",
在你完成package.json的更新后,执行:
$ npm install
注意:我建议使用官方Vue初始化套件以得到最好的支持版本,因为有时最新版本的依赖库并不会得到最好的支持。
最后,为你的主程序安装vuejs
库,你需要将其放在dependencies
中。
$ npm install --save vue
现在你可以使用WebPack构建你的应用,在你的root目录下执行:
$ webpack
你应该可以看到如下输出:
Hash: 6568e32467dc12c8aeeb
Version: webpack 1.12.9
Time: 743ms
Asset Size Chunks Chunk Names
build.js 246 kB 0 [emitted] main
+ 3 hidden modules
在你的浏览器中打开index.html
,如果你看到”Hello Vue”,那么至此一切OK,恭喜你,你有了一个基础的VueJS工程。
.vue
文件现在我们将要开始vuejs中很棒的一个部分:使用.vue
文件创建组件。
如下更新你的index.html
:
<html lang="en">
<head>
<meta charset="utf-8">
<title>Vue Exampletitle>
head>
<body>
<app>app>
<script src="dist/build.js">script>
body>
html>
注意,对比在body
节点中建立一个简单的视图模型(ViewModel),我们安装一个名为app
的组件并架设在
中。
如下修改你的main.js
:
import Vue from 'vue'
import App from './app.vue'
new Vue({
el: 'body',
components: { App }
})
现在,注意我们从app.vue
文件中提取了一个名为App
的新组件,并将其包含到body
元素的实例中。
我们将创建一个名为src/app.vue
的文件,将下列代码加入app.vue
中:
<template>
<div class="message">{{ msg }}div>
template>
<script>
export default {
data () {
return {
msg: 'Hello from vue-loader!'
}
}
}
script>
<style>
.message {
color: blue;
}
style>
在这个文件中:我们设置了一种样式,在script
中定义了行为,并在template
中定义了HTML模板。想要学习组件是如何工作的,你需要查看vuejs的文档。
现在我们重新执行webpack
并且看看会发生什么:
Hash: c71cc00f645706203ac4
Version: webpack 1.12.9
Time: 749ms
Asset Size Chunks Chunk Names
build.js 246 kB 0 [emitted] main
[3] ./src/app.vue 0 bytes [built] [failed]
+ 3 hidden modules
ERROR in ./src/app.vue
Module parse failed: /home/anirudh/work/misc/vue-scaffold/example/src/app.vue Line 1: Unexpected token <
You may need an appropriate loader to handle this file type.
|
| "message">{{ msg }}
|
@ ./src/main.js 7:11-31
Webpack不知道如何处理.vue
文件,幸运的是这很容易修改解决,打开你的webpack配置,更新如下代码:
module.exports = {
entry: './src/main.js',
output: {
path: './dist',
publicPath: 'dist/',
filename: 'build.js'
},
module: {
loaders: [
{
test: /\.js$/,
loader: 'babel',
exclude: /node_modules/
},
{
test: /\.vue$/,
loader: 'vue'
}
]
},
vue: {
loaders: {
js: 'babel'
}
}
}
现在,在你的package.json
的devDependencies
部分增加如下项:
"css-loader": "^0.23.0",
"style-loader": "^0.13.0",
"vue-loader": "^7.3.0",
"vue-html-loader": "^1.0.0",
执行npm install
来取得新的库
$ npm install
最后,再次执行webpack
,你会看到如下输出:
Hash: 740a1d3c85161f03a0cf
Version: webpack 1.12.9
Time: 1355ms
Asset Size Chunks Chunk Names
build.js 258 kB 0 [emitted] main
+ 11 hidden modules
如果你打开浏览器,你应该可以看到蓝色的”Hello from vue-loader”,这就意味着样式、HTML和javascript都被正确编译。作为奖励给你一张Darcy的照片。
热模块替换或热重载是JavaScript世界中最热的新技术,这允许你节约JavaScript文件并实时更新组件。
这是基础逻辑:
- 你写了一个应用。
- 你在浏览器中加载这个应用,并开始使用这个应用。
- 这个应用有一个’state’,Vue使用这个值来渲染页面。
如果你要做出改变或修复一个小bug,你需要重载这个页面,并重复所有步骤以使得应用回到初始state。
有了热重载,工程流程变得不同:
- 打开应用,将其带入给定的state
- 更新源码并保存
- Webpack检查修改,他会只重新编译改变的模块
- Webpack发送代码并使用如浏览器上的websockets改变在线应用
- Vue使用新的模块并热重载你的代码,重新展示你的页面的同时保持state完整
第一步,我们需要使用WebPack的开发服务但不是在浏览器中以一个html文件打开它。首先,更新package.json
中的devDependencies
:
"vue-hot-reload-api": "^1.2.0",
如下执行:
$ npm install
$ npm install -g webpack-dev-server
$ webpack-dev-server --inline --hot
当你运行webpack-dev-server
,你会看到一堆输出:
http://localhost:8080/
webpack result is served from /dist/
content is served from /home/anirudh/work/misc/vue-scaffold/example
Hash: ef5ed1df9062de968cb6
Version: webpack 1.12.9
Time: 1773ms
Asset Size Chunks Chunk Names
build.js 511 kB 0 [emitted] main
chunk {0} build.js (main) 465 kB [rendered]
[0] multi main 52 bytes {0} [built]
[2] (webpack)-dev-server/client?http://localhost:8080 2.48 kB {0} [built]
[3] (webpack)/~/url/url.js 22.3 kB {0} [built]
[... omitted for brevity ...]
[85] ./~/vue-html-loader!./~/vue-loader/lib/selector.js?type=template&index=0!./src/app.vue 58 bytes {0} [built]
[86] ./~/vue-hot-reload-api/index.js 5.62 kB {0} [built]
webpack: bundle is now VALID.
在浏览器中打开http://localhost:8080
,你会看到同样的输出,但这还没有显示出Vue的HMR有多棒。改变你的src/app.vue
:
<template>
<div class="message">Value is: {{ count }}div>
<a href="#" @click="increment">Incrementa>
template>
<script>
export default {
data () {
return {
count: 0
}
},
methods: {
increment () {
this.count ++;
}
}
}
script>
<style>
style>
重载http://localhost:8080
,你会看到一个计数器,同时有一个按钮,点击这个按钮,计数器就会增加。
现在,更新代码,你可以改变样式、改变按钮名称甚至是increment
功能改造,如果你保存了代码,组件便会更新。
你的工程可能并不需要所有这些东西,但这是你应该知道的vue相关内容。在你开始构建应用前,有一些事情是需要你花点时间搜索和创建的:
对于产品,你需要一个分离的压缩版的构建,你可以看看vuejs的建议vue-loader-example webpack config
注意,将你的webpack.config
移动到一个分离的文件夹需要你更多的配置。
测试在本教程范围之外,并且你的测试策略依赖于你的应用本身,可以看 vue-loader-example test example是如何测试的。
如果你的应用需要传统的CSS文件和图像,webpack可以帮助你,使用file-loader
,url-loader
等适当的加载器并提高开发流程。
你可以通过eslint-loader
配置eslint
,vue-loader-example是一个很好的例子,同时一个好的eslintrc
可以很好的保障eslint
的工作。