找了不少 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
文件夹中看到打包好的文件