找了不少 vue+webpack 構建的文章 感受這個仍是很不錯的,簡單易懂還有代碼實例。javascript
源碼連接:http://git.oschina.net/hwhao/webpack_vue_tutorials css
原文連接: https://github.com/varHarrie/Dawn-Blossoms/issues/7 html
提示: 代碼沒有敲錯。徹底能夠搭好的! 感受能夠的給做者一個星。
vue
推薦vue項目目錄結構:html5
config 全局變量java
dist 編譯後的項目代碼node
src 項目源碼webpack
modules vuex模塊git
types.js type管理es6
index.js 路由對象
routes.js 路由配置
apis api封裝
components Vue組件
libs js工具類
router 路由
store Vuex的store
styles css樣式
views 頁面組件
main.js vue入口文件
webpack.config Webpack各類環境的配置文件
package.json
全部項目的第一步固然是:建立項目文件夾,而後使用npm init -y
建立package.json
項目根目錄下創建src
和dist
文件夾,分別用來存放項目源碼
和webpack編譯後的代碼
在根目錄
下直接創建一個index.html
,做爲頁面的入口文件
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Demo</title> </head> <body> <div id="app">`message`</div> <!-- Vue模板入口 --> <script src="dist/main.js"></script></body> </html>
在src
下創建一個main.js
,做爲Vue的入口文件
// import...from的語法是ES6的,須要用到babel,後面再說// require的語法是Commonjs的,webpack已經實現了,能夠直接使用const Vue = require('vue')new Vue({ el: '#app', data: { message: 'Hello Vue.js!' } })
安裝模塊
安裝Vue:npm install vue@1 --save
安裝Webpack: npm install webpack --save-dev
使用webpack編譯打包
除非在全局安裝webpack
,使用本地安裝須要在package.json
的script
加入運行腳本,添加以後package.json
以下:
{ "name": "step2", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "dev": "webpack src/main.js dist/main.js" // <---添加這句 }, "keywords": [], "author": "", "license": "ISC", "dependencies": { "vue": "^1.0.28" }, "devDependencies": { "webpack": "^1.14.0" } }
運行npm run dev
,再用瀏覽器打開index.html
就能看到效果了:
Hello Vue.js!
上一步中直接使用webpack運行腳本webpack [入口文件] [出口文件]
,顯然對於後期添加webpack插件和不一樣環境的配置是不行的。
在項目根目錄下建立webpack.config
文件夾專門用於存放webpack的配置文件
爲了讓配置文件不一樣的編譯環境中可以複用(例如loaders
的配置,無論在開發環境仍是生產環境確定都是同樣的),在webpack.confg
中首先建立一個base.js
文件:
const path = require('path')const root = path.resolve(__dirname, '..') // 項目的根目錄絕對路徑module.exports = { entry: path.join(root, 'src/main.js'), // 入口文件路徑 output: { path: path.join(root, 'dist'), // 出口目錄 filename: 'main.js' // 出口文件名 } }
上面這段配置就實現了webpack src/main.js dist/main.js
的功能,還能夠額外拓展一下,變成:
const path = require('path')const root = path.resolve(__dirname, '..') // 項目的根目錄絕對路徑module.exports = { entry: path.join(root, 'src/main.js'), // 入口文件路徑 output: { path: path.join(root, 'dist'), // 出口目錄 filename: 'main.js' // 出口文件名 }, resolve: { alias: { // 配置目錄別名 // 在任意目錄下require('components/example') 至關於require('項目根目錄/src/components/example') components: path.join(root, 'src/components'), views: path.join(root, 'src/views'), styles: path.join(root, 'src/styles'), store: path.join(root, 'src/store') }, extensions: ['', '.js', '.vue'], // 引用js和vue文件能夠省略後綴名 fallback: [path.join(root, 'node_modules')] // 找不到的模塊會嘗試在這個數組的目錄裏面再尋找 }, resolveLoader: { fallback: [path.join(root, 'node_modules')] // 找不到的loader模塊會嘗試在這個數組的目錄裏面再尋找 }, module: { // 配置loader loaders: [ {test: /\.vue$/, loader: 'vue'}, // 全部.vue結尾的文件,使用vue-loader {test: /\.js$/, loader: 'babel', exclude: /node_modules/} // .js文件使用babel-loader,切記排除node_modules目錄 ] } }
根目錄下添加.babelrc
用於配置babel
:
{ "presets": ["es2015"] }
使用了vue-loader和babel-loader須要安裝包:
npm install --save-dev vue-loader@8 babel-loader babel-core babel-plugin-transform-runtime babel-preset-es2015 css-loader vue-style-loader vue-hot-reload-api@1 vue-html-loader
在webpack.confg
建立dev.js
文件:
const path = require('path')const webpack = require('webpack')const merge = require('webpack-merge')const baseConfig = require('./base')const root = path.resolve(__dirname, '..')module.exports = merge(baseConfig, {})
上面的代碼僅僅是導出了跟base.js
如出一轍的配置,下面咱們添加更多用於dev
(開發環境)的配置。
webpack-merge 用於合併兩個配置文件,須要安裝
npm install --save-dev webpack-merge
使用webpack dev server,開啓一個小型服務器,不須要再手動打開index.html
進行調試了
修改配置文件爲:
module.exports = merge(baseConfig, { devServer: { historyApiFallback: true, // 404的頁面會自動跳轉到/頁面 inline: true, // 文件改變自動刷新頁面 progress: true, // 顯示編譯進度 colors: true, // 使用顏色輸出 port: 3000, // 服務器端口 }, devtool: 'source-map' // 用於標記編譯後的文件與編譯前的文件對應位置,便於調試})
添加熱替換配置,每次改動文件不會再整個頁面都刷新
安裝webpack-dev-server
:npm install --save-dev webpack-dev-server
module.exports = merge(baseConfig, { entry: [ 'webpack/hot/dev-server', // 熱替換處理入口文件 path.join(root, 'src/index.js') ], devServer: { /* 同上 */}, plugins: [ new webpack.HotModuleReplacementPlugin() // 添加熱替換插件 ] }
使用HtmlWebpackPlugin
,實現js入口文件自動注入
module.exports = merge(baseConfig, { entry: [ /* 同上 */ ], devServer: { /* 同上 */ }, plugins: [ new webpack.HotModuleReplacementPlugin(), new HtmlWebpackPlugin({ template: path.join(root, 'index.html'), // 模板文件 inject: 'body' // js的script注入到body底部 }) ] }
最後修改後完整的dev.js
請查看源碼
這裏的
HotModuleReplacementPlugin
是webpack
內置的插件,不須要安裝但
HtmlWebpackPlugin
須要自行安裝:npm install --save-dev html-webpack-plugin
在文件頭中引入
const HtmlWebpackPlugin = require('html-webpack-plugin')
修改index.html
,去掉入口文件的引入:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Demo</title> </head> <body> <div id="app">`message`</div> <!-- Vue模板入口 --> <!-- 去掉js入口文件 --></body> </html>
最後修改package.json
中的webpack運行腳本爲:
{ "dev": "webpack-dev-server --config webpack.config/dev.js"}
爲了測試webpack配置是否都生效了,下面建立一個vue組件src/components/Hello.vue
:
<template> <div>`message`</div> </template><script> export default { data: () => ({message: 'Hello Vue.js!'}) }</script>
修改main.js
:
import Vue from 'vue'import Hello from './components/Hello.vue'new Vue({ el: '#app', template: '<div><hello></hello></div>', components: {Hello} })
運行npm run dev
,瀏覽器打開localhost:3000
查看結果:
Hello Vue.js!
安裝vue-router
: npm install --save vue-router@0.7
建立目錄
在src
目錄下建立views
文件夾,用於存放頁面組件
在src
目錄下建立router
文件夾,用於存放全部路由相關的配置
添加路由頁面
添加頁面組件src/views/Home.vue
:
<template> <div><hello></hello></div> </template><script> import Hello from 'components/Hello' export default { components: {Hello} }</script>
添加src/router/routes.js
文件,用於配置項目路由:
import Home from 'views/Home'export default { '/': { name: 'home', component: Home } }
添加路由入口文件src/router/index.js
:
import Vue from 'vue'import Router from 'vue-router'import routes from './routes'Vue.use(Router)const router = new Router({ hashbang: false, // 關閉hash模式 history: true, // 開啓html5history模式 linkActiveClass: 'active' // v-link激活時添加的class,默認是`v-link-active`})router.map(routes)router.beforeEach(({to, next}) => { console.log('---------> ' + to.name) // 每次調整路由時打印,便於調試 next() })export default router
修改main.js
:
import Vue from 'vue'import router from './router'const App = Vue.extend({})router.start(App, '#app')
最後別忘了編輯index.html
:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Demo</title> </head> <body> <div id="app"> <router-view></router-view><!--路由替換位置--> </div> </body> </html>
從新執行npm run dev
,瀏覽器打開localhost:3000
查看效果
vuex一般用於存放和管理不一樣組件中的共用狀態,例如不一樣路由頁面之間的公共數據
vuex中的幾個概念:
state:狀態,即數據
store:數據的集合,一個vuex引用,僅有一個store,包含n個state
mutation:state不能直接賦值,經過mutation定義最基本的操做
action:在action中調用一個或多個mutation
getter:state不能直接取值,使用getter返回須要的state
module:store和state之間的一層,便於大型項目管理,store包含多個module,module包含state、mutation和action
本教程中將以一個全局計數器做爲例子
安裝vuex
安裝vuex
:npm install --save vuex@1
添加src/store
文件夾,存放vuex相關文件,添加src/store/modules
用於vuex分模塊管理
添加src/store/types.js
,vuex的全部mutation type
都放在一塊兒,不建議分開多個文件,有效避免重名狀況:
export const INCREASE = 'INCREASE' // 累加export const RESET = 'RESET' // 清零
編寫vuex模塊,添加counter
模塊目錄store/modules/counter
添加store/modules/counter/actions.js
:
import {INCREASE, RESET} from 'store/types'export const increase = (({dispatch}) => { dispatch(INCREASE) // 調用type爲INCREASE的mutation})export const reset = (({dispatch}) => { dispatch(RESET) // 調用type爲RESET的mutation})
添加store/modules/counter/index.js
import{INCREASE, RESET} from 'store/types.js'const state = { count: 0}const mutations = { [INCREASE] (state) { state.count++ }, [RESET] (state) { state.count = 0 } }export default {state, mutations}
添加store/index.js
,做爲vuex入口文件
import Vue from 'vue'import Vuex from 'vuex'import counter from 'store/modules/counter'Vue.use(Vuex) // 確保在new Vuex.Store()以前export default new Vuex.Store({ modules: {counter} })
修改main.js
,將store引入並添加到App中:
import Vue from 'vue'import router from './router'import store from 'store'const App = Vue.extend({store})router.start(App, '#app')
最後改造一下src/components/Hello.vue
,把action用上:
<template> <div> <p>`message`</p> <p>click count: `count`</p> <button @click="increase">increase</button><!--能夠直接調用引入的action--> <button @click="reset">reset</button> </div> </template><script> import {increase, reset} from 'store/modules/counter/actions' // 引入action export default { data: () => ({message: 'Hello Vue.js!'}), vuex: { actions: {increase, reset}, getters: { count: ({counter}) => counter.count } } }</script>
eslint不是必須的,可是強烈建議用在全部的javascript項目中
對於我的開發,能夠在編程過程當中發現並提示語法錯誤,有效過濾各類低級錯誤
對於團隊開發,強制採用一致的編碼風格,保證項目的統一性,有效避免各類任性行爲
可是必定要注意,eslint定義的只是編碼風格,規則是死的,人是活的,學會利用自定義規則的功能,增減規則
同時要知道,eslint檢測不經過,不必定就是不能運行的,可能只是這種寫法違背了編碼風格,學會查看控制的查找具體錯誤緣由
想要更好的eslint體驗,請根據不一樣編輯器安裝對應的eslint插件,主流的編輯器均已有相應插件
選擇合適的編碼風格
eslint提供了許多rules,能夠直接在
.eslintrc
文件的rules
中一個一個的配置顯然咱們大多數狀況下不須要這麼作,網上已經有一些比較多人使用的風格了,本文推薦使用standard
配置.eslintrc
文件
根目錄下建立.eslintrc
文件:
{ "parser": "babel-eslint", // 支持babel "extends": "standard", // 使用eslint-config-standard的配置 "plugins": [ "html" // 支持.vue文件的檢測 ], "env": { "browser": true, // 不會將window上的全局變量判斷爲未定義的變量 "es6": true // 支持es6的語法 }, "rules": { // 自定義個別規則寫在這,0忽略,1警告,2報錯 "no-unused-vars": 1 // 將」未使用的變量「調整爲警告級別,原爲錯誤級別,更多規則請看官網 } }
結合不一樣編輯器的插件,打開js和vue文件中,就能看到提示了
根據使用的不一樣風格,安裝所需的包,本文安裝:
npm install --save-dev eslint babel-eslint eslint-config-standard eslint-plugin-standard eslint-plugin-html eslint-plugin-promise
前面已經配置過了開發環境下使用的配置文件dev.js
,對於生產環境,一般須要對編譯出來的文件進行壓縮處理,提取公共模塊等等,就須要專門提供一個配置文件
添加webpack.config/pro.js
文件,把生產環境用不到的刪掉,好比webpack-dev-server
、webpack-hot-replacement
const path = require('path')const webpack = require('webpack')const merge = require('webpack-merge')const HtmlWebpackPlugin = require('html-webpack-plugin')const baseConfig = require('./base')const root = path.resolve(__dirname, '..')module.exports = merge(baseConfig, { plugins: [ new HtmlWebpackPlugin({ template: path.join(root, 'index.html'), // 模板文件 inject: 'body' // js的script注入到body底部 }) ] })
webpack經常使用插件:
extract-text-webpack-plugin 提取css到單獨的文件
compression-webpack-plugin 壓縮gzip
webpack.optimize.UglifyJsPlugin 壓縮js文件,內置插件
webpack.DefinePlugin 定義全局變量,內置插件
webpack.optimize.CommonsChunkPlugin 提取公共依賴,內置插件
根據項目需求添加相應的插件,插件配置參數請查看官方文檔,這裏不進行羅列
在package.json
中添加運行腳本:"build": "webpack --config webpack.config/pro.js"
運行npm run build
,能夠在dist
文件夾中看到打包好的文件