一步步构造自己的vue2.0+webpack环境

SharonTucke 8年前
   <p style="text-align:center">前面vue2.0和webpack都已经有接触了些(vue.js入门, webpack入门之简单例子跑起来 ),现在开始学习如何构造自己的vue2.0+webpack环境。</p>    <p><img src="https://simg.open-open.com/show/5d9dc07443cf05fb593bf53ea1ca231e.jpg"></p>    <p><strong>1.首先新建一个目录vue-wkdemo,这是我们的项目目录。</strong>执行 npm init 命令生成package.json文件。执行npm init之后,会提示你填写一些项目的信息,一直回车默认就好了,或者直接执行 npm init -y 直接跳过询问步骤。 <img src="https://simg.open-open.com/show/a4180cb4a03020ebe6727c795f3f256a.gif"></p>    <p><strong>2.安装项目依赖项</strong></p>    <pre>  <code class="language-javascript">npm install webpack webpack-dev-server vue-loader vue-html-loader css-loader vue-style-loader  vue-hot-reload-api babel-loader babel-core babel-plugin-transform-runtime babel-preset-es2015 babel-runtime@5 --save-dev  npm install html-webpack-plugin --save-dev  </code></pre>    <pre>  <code class="language-javascript">npm install vue --save  </code></pre>    <p><strong>3.新建入口文件index.js,文件位置放置为:vue-wkdemo->app->index->index.js</strong></p>    <pre>  <code class="language-javascript">import Vue from 'Vue'  import Favlist from './components/Favlist.vue'  Vue.config.debug = true;//开启错误提示  window.onload = function () {    new Vue({        el: '#app',        components: {          'my-component': Favlist        }    });  }  </code></pre>    <p><strong>4.构建index.html模版,文件位置放置为:vue-wkdemo->app->index->index.html</strong></p>    <pre>  <code class="language-javascript"><!DOCTYPE html>  <html lang="zh">      <head>          <meta name="viewport" content="width=device-width, height=device-height, initial-scale=1.0, user-scalable=no">          <meta charset="utf-8">          <title>首页</title>      </head>      <body>        <div id="app">            <my-component></my-component>        </div>      </body>  </html>  </code></pre>    <p><strong>5.构建vue组件Favlist.vue ,文件放置为:vue-wkdemo->app->components->Favlist.vue</strong></p>    <pre>  <code class="language-javascript"><template id="template-home">    <div>      <div v-for="n in 10">div</div>    </div>  </template>      <style>  body {      color: red;  }  </style>  </code></pre>    <p><strong>6.构建 webpack.config.js ,文件放置为:vue-wkdemo->build->webpack.config.js</strong></p>    <pre>  <code class="language-javascript">// nodejs 中的path模块  var path = require('path');  var HtmlWebpackPlugin = require('html-webpack-plugin')    module.exports = {      // 入口文件,path.resolve()方法,可以结合我们给定的两个参数最后生成绝对路径,最终指向的就是我们的index.js文件      entry: path.resolve(__dirname, '../app/index/index.js'),      // 输出配置      output: {          // 输出路径是 myProject/output/static          path: path.resolve(__dirname, '../output/static'),          publicPath: 'static/',          filename: '[name].[hash].js',          chunkFilename: '[id].[chunkhash].js'      },      resolve: {          extensions: ['', '.js', '.vue'],          alias: {              'Vue': 'vue/dist/vue.js'          }      },      module: {            loaders: [              // 使用vue-loader 加载 .vue 结尾的文件              {                  test: /\.vue$/,                  loader: 'vue'              },              {                  test: /\.js$/,                  loader: 'babel?presets=es2015',                  exclude: /node_modules/              }          ]      },      Favlist: {          loaders: {              js: 'babel'          }      },      plugins: [          new HtmlWebpackPlugin({              filename: '../index.html',              template: path.resolve(__dirname, '../app/index/index.html'),              inject: true          })      ]  }    View Code</code></pre>    <p><strong>7.运行构建命令 : ‘webpack –display-modules –display-chunks –config build/webpack.config.js’</strong></p>    <p>可以看到输出文件:</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/8c7527f68c1d0c459f226ec3fe1f3eb4.png"></p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/fd15ea282111e822abae93beb2969ef6.png"></p>    <p><strong>8.到这里,我们的目录结构为:</strong></p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/e5198bf51c33ba2ba97c66939f1cef90.png"></p>    <p>运行output->static->index.html这个文件,过程中遇到各种各样的坑 <img src="https://simg.open-open.com/show/4fdfe664337ba4405fe73e9d800be559.jpg"> (省略几百字。。。)</p>    <p>最后终于看到结果了!!! <img src="https://simg.open-open.com/show/a2ca8c108aca4abdfef6f12d1921ed71.gif"></p>    <p><img src="https://simg.open-open.com/show/b0d973e58650dd74f88d1914bc99961a.png"></p>    <p><strong>9.问题来了,每次都需要运行构建命令才能查看改变后的代码效果,</strong>这是很没有效率 <img src="https://simg.open-open.com/show/cdf04d599a1cbf94d008010ab2a2643d.jpg"> ,于是还需要安装  webpack-dev-middleware 中间件和 webpack-hot-middleware 中间件</p>    <pre>  <code class="language-javascript">npm install webpack-dev-middleware webpack-hot-middleware --save-dev  </code></pre>    <p>另外还需要安装express</p>    <pre>  <code class="language-javascript">npm install express --save-dev  </code></pre>    <p>介绍下 webpack-dev-middleware 中间件,它是对webpack一个简单的包装,它可以通过连接服务器服务那些从webpack发射出来的文件,它有一下几点好处:</p>    <p>1、不会向硬盘写文件,而是在内存中,注意我们构建项目实际就是向硬盘写文件。</p>    <p>2、当文件改变的时候,这个中间件不会再服务旧的包,你可以直接刷新浏览器就能看到最新的效果,这样你就不必等待构建的时间,所见即所得。</p>    <p>在build目录中创建一个dev-server.js文件,并写入内容:</p>    <pre>  <code class="language-javascript">// 引入必要的模块  var express = require('express')  var webpack = require('webpack')  var config = require('./webpack.config')    // 创建一个express实例  var app = express()    // 调用webpack并把配置传递过去  var compiler = webpack(config)    // 使用 webpack-dev-middleware 中间件  var devMiddleware = require('webpack-dev-middleware')(compiler, {      publicPath: config.output.publicPath,      stats: {          colors: true,          chunks: false      }  })    // 注册中间件  app.use(devMiddleware)    // 监听 8888端口,开启服务器  app.listen(8888, function (err) {      if (err) {          console.log(err)          return      }      console.log('Listening at http://localhost:8888')  })    View Code</code></pre>    <p>然后我们修改 webpack.config.js 配置文件</p>    <p>① 将 config.output.publicPath 修改为 ‘/‘:</p>    <pre>  <code class="language-javascript">// 输出配置      output: {          // 输出路径是 myProject/output/static          path: path.resolve(__dirname, '../output/static'),          publicPath: '/',          filename: '[name].[hash].js',          chunkFilename: '[id].[chunkhash].js'      },  </code></pre>    <p>② 将 plugins 中 HtmlWebpackPlugin 中的 filename 修改为 ‘app/index/index.html’</p>    <pre>  <code class="language-javascript"> plugins: [          new HtmlWebpackPlugin({              filename: 'app/index/index.html',              template: path.resolve(__dirname, '../app/index/index.html'),              inject: true          })      ]  </code></pre>    <p>此时,我们在项目根目录运行下面的命令,开启服务:</p>    <pre>  <code class="language-javascript">node build/dev-server.js  </code></pre>    <p>在浏览器中输入 http://localhost:8888/app/index/index.html,如果成功了将和前面本地运行output->static->index.html这个文件的结果是一样一样的</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/f305cafff38b5aed11493e63dd5c97c3.png"> 不信? <img src="https://simg.open-open.com/show/d0a6463fecb8b94839e574fd4b16d768.jpg"></p>    <p>为了不去修改webpack.config.js,在build目录下新建一个webpack.dev.conf.js文件,意思是开发模式下要读取的配置文件,并写入一下内容:</p>    <pre>  <code class="language-javascript">var HtmlWebpackPlugin = require('html-webpack-plugin')  var path = require('path');  // 引入基本配置  var config = require('./webpack.config');    config.output.publicPath = '/';    config.plugins = [      new HtmlWebpackPlugin({          filename: 'app/index/index.html',          template: path.resolve(__dirname, '../app/index/index.html'),          inject: true      })  ];    module.exports = config;    View Code</code></pre>    <p>这样在dev环境下的配置文件覆盖了基本配置文件,只需要在dev-server.js中将</p>    <pre>  <code class="language-javascript">var config = require('./webpack.config')  </code></pre>    <p>改为:</p>    <pre>  <code class="language-javascript">var config = require('./webpack.dev.conf')  </code></pre>    <p>到这里,我们已经使用webpack-dev-middleware 搭建基本的开发环境了,但是每次修改代码后,还是需要我们手动刷新浏览器,接下来介绍热加载(所谓的热加载,意思就是说能够追踪我们代码的变化,并自动更新界面,甚至还能保留程序状态。),我们需要 webpack-hot-middleware 中间件来完成热加载。</p>    <p>配合 webpack-dev-middleware 使用,我们还需要做的是:</p>    <p>第一步:安装(上面我们已经安装过)</p>    <pre>  <code class="language-javascript">npm install webpack-dev-middleware --save-dev</code></pre>    <p>第二步:在 webpack.dev.conf.js 配置文件中添加三个插件,如下:</p>    <pre>  <code class="language-javascript">var HtmlWebpackPlugin = require('html-webpack-plugin')  var path = require('path');  var webpack = require('webpack');  // 引入基本配置  var config = require('./webpack.config');    config.output.publicPath = '/';    config.plugins = [      // 添加三个插件      new webpack.optimize.OccurenceOrderPlugin(),      new webpack.HotModuleReplacementPlugin(),      new webpack.NoErrorsPlugin(),        new HtmlWebpackPlugin({          filename: 'app/index/index.html',          template: path.resolve(__dirname, '../app/index/index.html'),          inject: true      })  ];    module.exports = config;  </code></pre>    <p>第三步:在 webpack.config.js 文件中入口配置中添加 ‘webpack-hot-middleware/client’,如下:</p>    <pre>  <code class="language-javascript">entry: ['webpack-hot-middleware/client', path.resolve(__dirname, '../app/index/index.js')],  </code></pre>    <p>第四步:在 dev-server.js 文件中使用插件</p>    <pre>  <code class="language-javascript">// 引入必要的模块  var express = require('express')  var webpack = require('webpack')  var config = require('./webpack.dev.conf')    // 创建一个express实例  var app = express()    // 调用webpack并把配置传递过去  var compiler = webpack(config)    // 使用 webpack-dev-middleware 中间件  var devMiddleware = require('webpack-dev-middleware')(compiler, {      publicPath: config.output.publicPath,      stats: {          colors: true,          chunks: false      }  })    // 使用 webpack-hot-middleware 中间件  var hotMiddleware = require('webpack-hot-middleware')(compiler)    // 注册中间件  app.use(devMiddleware)  // 注册中间件  app.use(hotMiddleware)    // 监听 8888端口,开启服务器  app.listen(8888, function (err) {      if (err) {          console.log(err)          return      }      console.log('Listening at http://localhost:8888')  })  </code></pre>    <p>现在重启的服务,然后修改 Favlist.vue 中的页面颜色为 ‘black’:</p>    <pre>  <code class="language-javascript"><style>    body {        color: black;    }  </style>  </code></pre>    <p>一保存就可以看到修改后的效果,不需要手动刷新浏览器啦啦啦~\(≧▽≦)/~啦啦啦。</p>    <p>刚刚修改了webpack.config.js这个基本配置文件中的入口配置,为了不修改这个基本配置文件,我们在webpack.dev.conf.js文件中需要改下配置:</p>    <pre>  <code class="language-javascript">var HtmlWebpackPlugin = require('html-webpack-plugin')  var path = require('path');  var webpack = require('webpack');  // 引入基本配置  var config = require('./webpack.config');    config.output.publicPath = '/';    config.plugins = [      new webpack.optimize.OccurenceOrderPlugin(),      new webpack.HotModuleReplacementPlugin(),      new webpack.NoErrorsPlugin(),      new HtmlWebpackPlugin({          filename: 'app/index/index.html',          template: path.resolve(__dirname, '../app/index/index.html'),          inject: true      })  ];    // 动态向入口配置中注入 webpack-hot-middleware/client  var devClient = 'webpack-hot-middleware/client';  Object.keys(config.entry).forEach(function (name, i) {      var extras = [devClient]      config.entry[name] = extras.concat(config.entry[name])  })    module.exports = config;    View Code</code></pre>    <p>然后将 webpack.config.js 文件中的入口配置修改为以下配置方式:</p>    <pre>  <code class="language-javascript">entry: {          index: [              path.resolve(__dirname, '../app/index/index.js')          ]      },  </code></pre>    <p>重启服务,修改 Favlist.vue 中的背景色,再次查看浏览器,发现可以热加载。到这里还没结束,这里只是监听到Favlist.vue文件的改动,为了能监听到index.html文件的改动,我们还需要做一些工作。</p>    <p>第一步:在dev-server.js文件中监听html文件改变事件,修改后的dev-server.js文件如下:</p>    <pre>  <code class="language-javascript">// 引入必要的模块  var express = require('express')  var webpack = require('webpack')  var config = require('./webpack.dev.conf')    // 创建一个express实例  var app = express()    // 调用webpack并把配置传递过去  var compiler = webpack(config)    // 使用 webpack-dev-middleware 中间件  var devMiddleware = require('webpack-dev-middleware')(compiler, {      publicPath: config.output.publicPath,      stats: {          colors: true,          chunks: false      }  })    var hotMiddleware = require('webpack-hot-middleware')(compiler)    // webpack插件,监听html文件改变事件  compiler.plugin('compilation', function (compilation) {      compilation.plugin('html-webpack-plugin-after-emit', function (data, cb) {          // 发布事件          hotMiddleware.publish({ action: 'reload' })          cb()      })  })    // 注册中间件  app.use(devMiddleware)  // 注册中间件  app.use(hotMiddleware)    // 监听 8888端口,开启服务器  app.listen(8888, function (err) {      if (err) {          console.log(err)          return      }      console.log('Listening at http://localhost:8888')  })    View Code</code></pre>    <p>第二步:修改webpack.dev.conf.js文件</p>    <pre>  <code class="language-javascript">var HtmlWebpackPlugin = require('html-webpack-plugin')  var path = require('path');  var webpack = require('webpack');  // 引入基本配置  var config = require('./webpack.config');    config.output.publicPath = '/';    config.plugins = [      new webpack.optimize.OccurenceOrderPlugin(),      new webpack.HotModuleReplacementPlugin(),      new webpack.NoErrorsPlugin(),      new HtmlWebpackPlugin({          filename: 'app/index/index.html',          template: path.resolve(__dirname, '../app/index/index.html'),          inject: true      })  ];    // 动态向入口配置中注入 webpack-hot-middleware/client  // var devClient = 'webpack-hot-middleware/client';  var devClient = './build/dev-client';  Object.keys(config.entry).forEach(function (name, i) {      var extras = [devClient]      config.entry[name] = extras.concat(config.entry[name])  })    module.exports = config;    View Code</code></pre>    <p>文件中修改了devClient变量,将 ‘webpack-hot-middleware/client’ 替换成 ‘./build/dev-client’,最终会导致,我们入口配置会变成下面这样:</p>    <pre>  <code class="language-javascript">   entry: {          index: [              './build/dev-client',              path.resolve(__dirname, '../app/index/index.js')          ]      },  </code></pre>    <p>第三步:新建build/dev-client.js文件,并编辑如下内容:</p>    <pre>  <code class="language-javascript">var hotClient = require('webpack-hot-middleware/client')    // 订阅事件,当 event.action === 'reload' 时执行页面刷新  hotClient.subscribe(function (event) {      if (event.action === 'reload') {          window.location.reload()      }  })  </code></pre>    <p>这里我们除了引入 ‘webpack-hot-middleware/client’ 之外订阅了一个事件,当 event.action === ‘reload’ 时触发,而在 dev-server.js 中有发布的事件:</p>    <pre>  <code class="language-javascript">// webpack插件,监听html文件改变事件  compiler.plugin('compilation', function (compilation) {      compilation.plugin('html-webpack-plugin-after-emit', function (data, cb) {          // 发布事件          hotMiddleware.publish({ action: 'reload' })          cb()      })  })  </code></pre>    <p>这样,当我们的html文件改变后,就可以监听的到,最终会执行页面刷新,而不需要我们手动刷新。看下效果:</p>    <p><img src="https://simg.open-open.com/show/9b762948906db1f8b42cafa5a033d562.gif"></p>    <p>至此,开发环境终于搞定了。</p>    <p> </p>    <p> </p>    <p>来自:http://www.cnblogs.com/wj204/p/6031435.html</p>    <p> </p>