译文地址

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。

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>Vue Example</title>
  </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应用的骨架,但他还需要构建完成。

第二部分:基础webpack构建

在你的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依赖es2015preset(支持下一代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-loader和.vue文件

现在我们将要开始vuejs中很棒的一个部分:使用.vue文件创建组件。
如下更新你的index.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>Vue Example</title>
  </head>
  <body>
    <app></app>
    <script src="dist/build.js"></script>
  </body>
</html>

注意,对比在body节点中建立一个简单的视图模型(ViewModel),我们安装一个名为app的组件并架设在<app></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.
| <template>
| <div class="message">{{ msg }}</div>
| </template>
 @ ./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.jsondevDependencies部分增加如下项:

    "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">Increment</a>
</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工作

如果你的应用需要传统的CSS文件和图像,webpack可以帮助你,使用file-loaderurl-loader等适当的加载器并提高开发流程。

注意

你可以通过eslint-loader配置eslintvue-loader-example是一个很好的例子,同时一个好的eslintrc可以很好的保障eslint的工作。

Logo

前往低代码交流专区

更多推荐