前面vue2.0和webpack都已經有接觸了些(vue.js入門,webpack入門之簡單例子跑起來),如今開始學習如何構造本身的vue2.0+webpack環境。css
1.首先新建一個目錄vue-wkdemo,這是咱們的項目目錄。執行 npm init 命令生成package.json文件。執行npm init以後,會提示你填寫一些項目的信息,一直回車默認就行了,或者直接執行 npm init -y 直接跳過詢問步驟。html
2.安裝項目依賴項vue
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
npm install vue --save
3.新建入口文件index.js,文件位置放置爲:vue-wkdemo->app->index->index.jsnode
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 } }); }
4.構建index.html模版,文件位置放置爲:vue-wkdemo->app->index->index.htmlwebpack
<!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>
5.構建vue組件Favlist.vue ,文件放置爲:vue-wkdemo->app->index->components->Favlist.vue git
<template id="template-home"> <div> <div v-for="n in 10">div</div> </div> </template>
<style> body { color: red; } </style>
6.構建 webpack.config.js ,文件放置爲:vue-wkdemo->build->webpack.config.jsgithub
// 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 }) ] }
7.運行構建命令 :web
webpack --display-modules --display-chunks --config build/webpack.config.js
能夠看到輸出文件:express
8.到這裏,咱們的目錄結構爲:npm
運行output->static->index.html這個文件,過程當中遇到各類各樣的坑(省略幾百字。。。)
最後終於看到結果了!!!
9.問題來了,每次都須要運行構建命令才能查看改變後的代碼效果,這是很沒有效率,因而還須要安裝 webpack-dev-middleware中間件和webpack-hot-middleware 中間件
npm install webpack-dev-middleware webpack-hot-middleware --save-dev
另外還須要安裝express
npm install express --save-dev
介紹下webpack-dev-middleware中間件,它是對webpack一個簡單的包裝,它能夠經過鏈接服務器服務那些從webpack發射出來的文件,它有一下幾點好處:
一、不會向硬盤寫文件,而是在內存中,注意咱們構建項目實際就是向硬盤寫文件。
二、當文件改變的時候,這個中間件不會再服務舊的包,你能夠直接刷新瀏覽器就能看到最新的效果,這樣你就沒必要等待構建的時間,所見即所得。
在build目錄中建立一個dev-server.js文件,並寫入內容:
// 引入必要的模塊 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') })
而後咱們修改 webpack.config.js 配置文件
① 將 config.output.publicPath 修改成 ‘/‘:
// 輸出配置 output: { // 輸出路徑是 myProject/output/static path: path.resolve(__dirname, '../output/static'), publicPath: '/', filename: '[name].[hash].js', chunkFilename: '[id].[chunkhash].js' },
② 將 plugins 中 HtmlWebpackPlugin 中的 filename 修改成 ‘app/index/index.html’
plugins: [ new HtmlWebpackPlugin({ filename: 'app/index/index.html', template: path.resolve(__dirname, '../app/index/index.html'), inject: true }) ]
此時,咱們在項目根目錄運行下面的命令,開啓服務:
node build/dev-server.js
在瀏覽器中輸入 http://localhost:8888/app/index/index.html,若是成功了將和前面本地運行output->static->index.html這個文件的結果是同樣同樣的
不信?
爲了避免去修改webpack.config.js,在build目錄下新建一個webpack.dev.conf.js文件,意思是開發模式下要讀取的配置文件,並寫入一下內容:
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;
這樣在dev環境下的配置文件覆蓋了基本配置文件,只須要在dev-server.js中將
var config = require('./webpack.config')
改成:
var config = require('./webpack.dev.conf')
到這裏,咱們已經使用webpack-dev-middleware 搭建基本的開發環境了,可是每次修改代碼後,仍是須要咱們手動刷新瀏覽器,接下來介紹熱加載(所謂的熱加載,意思就是說可以追蹤咱們代碼的變化,並自動更新界面,甚至還能保留程序狀態。),咱們須要 webpack-hot-middleware 中間件來完成熱加載。
配合 webpack-dev-middleware 使用,咱們還須要作的是:
第一步:安裝(上面咱們已經安裝過)
npm install webpack-dev-middleware --save-dev
第二步:在 webpack.dev.conf.js 配置文件中添加三個插件,以下:
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;
第三步:在 webpack.config.js 文件中入口配置中添加 ‘webpack-hot-middleware/client’,以下:
entry: ['webpack-hot-middleware/client', path.resolve(__dirname, '../app/index/index.js')],
第四步:在 dev-server.js 文件中使用插件
// 引入必要的模塊 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') })
如今重啓的服務,而後修改 Favlist.vue 中的頁面顏色爲 ‘black’:
<style>
body {
color: black;
}
</style>
一保存就能夠看到修改後的效果,不須要手動刷新瀏覽器啦啦啦~\(≧▽≦)/~啦啦啦。
剛剛修改了webpack.config.js這個基本配置文件中的入口配置,爲了避免修改這個基本配置文件,咱們在webpack.dev.conf.js文件中須要改下配置:
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;
而後將 webpack.config.js 文件中的入口配置修改成如下配置方式:
entry: { index: [ path.resolve(__dirname, '../app/index/index.js') ] },
重啓服務,修改 Favlist.vue 中的背景色,再次查看瀏覽器,發現能夠熱加載。到這裏還沒結束,這裏只是監聽到Favlist.vue文件的改動,爲了能監聽到index.html文件的改動,咱們還須要作一些工做。
第一步:在dev-server.js文件中監聽html文件改變事件,修改後的dev-server.js文件以下:
// 引入必要的模塊 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') })
第二步:修改webpack.dev.conf.js文件
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;
文件中修改了devClient變量,將 ‘webpack-hot-middleware/client’ 替換成 ‘./build/dev-client’,最終會致使,咱們入口配置會變成下面這樣:
entry: { index: [ './build/dev-client', path.resolve(__dirname, '../app/index/index.js') ] },
第三步:新建build/dev-client.js文件,並編輯以下內容:
var hotClient = require('webpack-hot-middleware/client') // 訂閱事件,當 event.action === 'reload' 時執行頁面刷新 hotClient.subscribe(function (event) { if (event.action === 'reload') { window.location.reload() } })
這裏咱們除了引入 ‘webpack-hot-middleware/client’ 以外訂閱了一個事件,當 event.action === ‘reload’ 時觸發,而在 dev-server.js 中有發佈的事件:
// webpack插件,監聽html文件改變事件 compiler.plugin('compilation', function (compilation) { compilation.plugin('html-webpack-plugin-after-emit', function (data, cb) { // 發佈事件 hotMiddleware.publish({ action: 'reload' }) cb() }) })
這樣,當咱們的html文件改變後,就能夠監聽的到,最終會執行頁面刷新,而不須要咱們手動刷新。看下效果:
至此,開發環境終於搞定了。
源代碼放在個人github上了【vue+webpack】,搭建過程當中我遇到不少問題,雖然沒記錄下來,可是應該也是有印象的,你們能夠留言問。最後推薦一下這篇【webpack+vuejs基本配置】,經過這篇文章的學習,我纔有這麼多收穫,感恩O(∩_∩)O
---更新webpack2 配置過程當中出現的問題 17.02.08 16:39---
今天有網友Yeaseon提出webpack2配置中出現的問題,我跟着實驗了一下,發現確實有問題,更正了一些文件配置後,最後是成功了
一: 依賴文件package.json
{ "name": "vue-webpack-demo", "version": "1.0.0", "description": "vue webpack demo", "main": "index.js", "scripts": { "build": "babel input.js -o compiled.js" }, "repository": { "type": "git", "url": "git" }, "keywords": [ "vue", "webpack" ], "author": "wangjuan", "license": "ISC", "devDependencies": { "babel-core": "^6.22.1", "babel-loader": "^6.2.10", "babel-plugin-transform-runtime": "^6.22.0", "babel-preset-es2015": "^6.22.0", "babel-runtime": "^5.8.38", "css-loader": "^0.26.1", "html-webpack-plugin": "^2.28.0", "vue": "^2.1.10", "vue-hot-reload-api": "^2.0.8", "vue-html-loader": "^1.2.3", "vue-loader": "^10.3.0", "vue-style-loader": "^2.0.0", "vue-template-compiler": "^2.1.10", "webpack": "^2.2.1", "webpack-dev-server": "^2.3.0" }, "dependencies": { "vue": "^2.0.3" } }
二:webpack.config.js文件
// nodejs 中的path模塊 var path = require('path'); var HtmlWebpackPlugin = require('html-webpack-plugin') module.exports = { // 入口文件,path.resolve()方法,能夠結合咱們給定的兩個參數最後生成絕對路徑,最終指向的就是咱們的index.js文件 entry: { index: [ './build/dev-client.js', path.resolve(__dirname, '../app/index/index.js') ] }, // 輸出配置 output: { // 輸出路徑是 myProject/output/static path: path.resolve(__dirname, '../output/static'), publicPath: '/', 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-loader' }, { test: /\.js$/, loader: 'babel-loader?presets=es2015', exclude: /node_modules/ } ] }, plugins: [ new HtmlWebpackPlugin({ filename: 'app/index/index.html', template: path.resolve(__dirname, '../app/index/index.html'), inject: true, }) ] }
注意:1.後面要加上loader。
2..js後綴不能省略。
3. 注意這裏的空格。
三:webpack.dev.conf.js文件
var HtmlWebpackPlugin = require('html-webpack-plugin') var path = require('path'); var webpack = require('webpack'); // 引入基本配置 var config = require('./webpack.config.js'); config.output.publicPath = '/'; config.plugins = [ new webpack.optimize.OccurrenceOrderPlugin(), 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;
經過參考 知道這個方法已經被重命名,改成如今的就ok