搭建 Webpack+Vue+vuex+vue-router 項目

找了不少 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

第一步:初始化項目

  1. 全部項目的第一步固然是:建立項目文件夾,而後使用npm init -y建立package.json

  2. 項目根目錄下創建srcdist文件夾,分別用來存放項目源碼webpack編譯後的代碼

第二步:入口文件

  1. 根目錄下直接創建一個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>
  1. src下創建一個main.js,做爲Vue的入口文件

// import...from的語法是ES6的,須要用到babel,後面再說// require的語法是Commonjs的,webpack已經實現了,能夠直接使用const Vue = require('vue')new Vue({
  el: '#app',
  data: {
    message: 'Hello Vue.js!'
  }
})
  1. 安裝模塊

安裝Vue:npm install vue@1 --save
安裝Webpack: npm install webpack --save-dev

  1. 使用webpack編譯打包

除非在全局安裝webpack,使用本地安裝須要在package.jsonscript加入運行腳本,添加以後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插件和不一樣環境的配置是不行的。

  1. 在項目根目錄下建立webpack.config文件夾專門用於存放webpack的配置文件

  2. 爲了讓配置文件不一樣的編譯環境中可以複用(例如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

  1. 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

  1. 使用webpack dev server,開啓一個小型服務器,不須要再手動打開index.html進行調試了

修改配置文件爲:

module.exports = merge(baseConfig, {
  devServer: {
    historyApiFallback: true, // 404的頁面會自動跳轉到/頁面
    inline: true, // 文件改變自動刷新頁面
    progress: true, // 顯示編譯進度
    colors: true, // 使用顏色輸出
    port: 3000, // 服務器端口
  },
  devtool: 'source-map' // 用於標記編譯後的文件與編譯前的文件對應位置,便於調試})
  1. 添加熱替換配置,每次改動文件不會再整個頁面都刷新

安裝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() // 添加熱替換插件
  ]
}
  1. 使用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請查看源碼

這裏的HotModuleReplacementPluginwebpack內置的插件,不須要安裝

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>
  1. 最後修改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!

第四步:配置路由

  1. 安裝vue-routernpm install --save vue-router@0.7

  2. 建立目錄

src目錄下建立views文件夾,用於存放頁面組件
src目錄下建立router文件夾,用於存放全部路由相關的配置

  1. 添加路由頁面

添加頁面組件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一般用於存放和管理不一樣組件中的共用狀態,例如不一樣路由頁面之間的公共數據

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

本教程中將以一個全局計數器做爲例子

  1. 安裝vuex

安裝vuexnpm install --save vuex@1
添加src/store文件夾,存放vuex相關文件,添加src/store/modules用於vuex分模塊管理

  1. 添加src/store/types.js,vuex的全部mutation type都放在一塊兒,不建議分開多個文件,有效避免重名狀況:

export const INCREASE = 'INCREASE' // 累加export const RESET = 'RESET' // 清零
  1. 編寫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}
  1. 添加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}
})
  1. 修改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')
  1. 最後改造一下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

eslint不是必須的,可是強烈建議用在全部的javascript項目中

對於我的開發,能夠在編程過程當中發現並提示語法錯誤,有效過濾各類低級錯誤

對於團隊開發,強制採用一致的編碼風格,保證項目的統一性,有效避免各類任性行爲

可是必定要注意,eslint定義的只是編碼風格,規則是死的,人是活的,學會利用自定義規則的功能,增減規則

同時要知道,eslint檢測不經過,不必定就是不能運行的,可能只是這種寫法違背了編碼風格,學會查看控制的查找具體錯誤緣由

想要更好的eslint體驗,請根據不一樣編輯器安裝對應的eslint插件,主流的編輯器均已有相應插件

  1. 選擇合適的編碼風格

eslint提供了許多rules,能夠直接在.eslintrc文件的rules中一個一個的配置

顯然咱們大多數狀況下不須要這麼作,網上已經有一些比較多人使用的風格了,本文推薦使用standard

  1. 配置.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

第七步:webpack生產環境配置

前面已經配置過了開發環境下使用的配置文件dev.js,對於生產環境,一般須要對編譯出來的文件進行壓縮處理,提取公共模塊等等,就須要專門提供一個配置文件

  1. 添加webpack.config/pro.js文件,把生產環境用不到的刪掉,好比webpack-dev-serverwebpack-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 提取公共依賴,內置插件

根據項目需求添加相應的插件,插件配置參數請查看官方文檔,這裏不進行羅列

  1. package.json中添加運行腳本:"build": "webpack --config webpack.config/pro.js"

  2. 運行npm run build,能夠在dist文件夾中看到打包好的文件

相關文章
相關標籤/搜索