一、用 vue-cli 克隆一个官方的模板
安装vue-cli组件
cnpm install -g vue-cli
创建一个官方的模板项目。
vue init webpack-simple vue-demo
cd vue-demo
cnpm install
二、安装组件
# 常用的loaders
cnpm install --save-dev json-loader
cnpm install --save-dev css-loader style-loader postcss-loader autoprefixer
cnpm install --save-dev image-webpack-loader url-loader file-loader
# js/jsx 处理平台
cnpm install --save-dev babel-core babel-loader babel-register babel-plugin-transform-runtime babel-runtime babel-plugin-component
cnpm install --save-dev babel-preset-es2015 babel-preset-stage-0 babel-preset-stage-2
# eslint 环境
cnpm install --save-dev eslint-loader babel-eslint
cnpm install --save-dev eslint-config-vue eslint-config-standard vue-template-compiler eslint-friendly-formatter
cnpm install --save-dev eslint eslint-plugin-vue eslint-plugin-flow-vars eslint-plugin-promise eslint-plugin-standard eslint-plugin-html
# vue 组件
cnpm install --save vue
cnpm install --save-dev vue-loader vue-html-loader vue-style-loader vue-template-compiler
# webpack
cnpm install --save-dev cross-env@beta webpack@beta webpack-dev-server@beta
cnpm install -g cross-env@beta webpack@beta webpack-dev-server@beta
cnpm install --save-dev html-webpack-plugin copy-webpack-plugin clean-webpack-plugin # HTML模板插件/文件复制插件/目录清理插件
cnpm install --save-dev extract-text-webpack-plugin@beta # 分离css插件
三、编辑配置文件
3.1 编辑 webpack.config.js
var path = require('path') // `output.path`必须是一个绝对路径
var webpack = require('webpack')
var HtmlWebpackPlugin = require('html-webpack-plugin')
var ExtractTextPlugin = require('extract-text-webpack-plugin') // 分离css文件的插件
// var CopyWebpackPlugin = require('copy-webpack-plugin') // 复制文件和目录的插件
var CleanWebpackPlugin = require('clean-webpack-plugin') // 清理dist目录插件
// webpack.base.config 基本配置
module.exports = {
entry: ['./src/main.js'],
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.[hash].js'
},
module: {
rules: [
{test: /\.json$/i, loader: 'json-loader'},
{test: /\.(css|sass|less|scss)$/i, loader: ExtractTextPlugin.extract({fallbackLoader: 'style-loader', loader: 'css-loader?modules!postcss-loader'})},
{test: /\.vue$/i, loader: 'vue-loader'},
{test: /\.js?$/i, loader: 'babel-loader', exclude: /node_modules/}, // .js .jsx 文件通过label平台处理,配置文件.babelrc
{test: /\.(woff|eot|ttf)$/i, loader: 'url-loader', query: {limit: 8192, name: 'fonts/[name].[ext]?[hash]'}},
// 先通过 image-webpack-loader 将图片进行优化,
// 然后由url-loader处理,当图片大小小于8k时,将图片转换为base64字节,当图片大于8k时输出到 imgs/[hash].[ext]
{test: /\.(png|jp?g|gif|svg)$/i, loaders: [{loader: 'url-loader', query: {limit: 8192, name: 'imgs/[hash].[ext]'}}, {loader: 'image-webpack-loader', query: {progressive: true, optimizationLevel: 8, interlaced: false, pngquant: {quality: '70-90', speed: 4}}}]}
]
},
resolve: { // 请求重定向,应用于 `require` 语句
alias: {'vue$': 'vue/dist/vue.common.js'} // 使用别名进行重定向,它和扩展名(externals)重定向不能同时使用。
},
plugins: [
new webpack.LoaderOptionsPlugin({options: {
postcss: function () { return [require('autoprefixer'), require('precss')] }
}}),
new webpack.NoErrorsPlugin(), // 允许错误不打断程序
new ExtractTextPlugin('style.css?[hash]'), // 分离的 css 输出文件名
// new CopyWebpackPlugin([{from: './src/public', to: 'public'}]), // 复制公共文件
new HtmlWebpackPlugin({template: './src/main.tpl', filename: 'index.html', inject: 'body', minify: {removeComments: true, collapseWhitespace: true}}) // HTML模板
]
}
// webpack.dev.config 开发环境配置
if (process.env.NODE_ENV === 'development') {
module.exports.plugins = (module.exports.plugins || []).concat([
new webpack.HotModuleReplacementPlugin() // 全局开启代码热替换
])
module.exports.devServer = { // 本地服务器配置
port: 8080,
host: 'localhost',
historyApiFallback: true,
noInfo: true,
contentBase: './dist' // 目录
}
module.exports.devtool = 'cheap-module-eval-source-map' // sourceMap 选项,用于调试和定位
};
// webpack.prod.config.js 项目打包配置
if (process.env.NODE_ENV === 'production') {
module.exports.plugins = (module.exports.plugins || []).concat([
new webpack.DefinePlugin({'process.env': {NODE_ENV: '"production"'}}),
new CleanWebpackPlugin(['./dist'], {verbose: true, dry: false, exclude: []}), // 打包前先删除 dist 目录
// new webpack.optimize.CommonsChunkPlugin('commons.[hash].js'), //提取公用函数
new webpack.optimize.UglifyJsPlugin({sourceMap: true, compress: {warnings: false}}), // 压缩打包的文件,但不包括js文件。ps: js文件通过 `webpack -p` 压缩
new webpack.BannerPlugin('Written by Bing.Rowe, Compiled at ' + new Date().toLocaleString()) // 给文件添加编译时间
])
module.exports.devtool = 'cheap-module-source-map'
}
3.2 ESLint 配置文件
创建 .eslintignore
,表明 eslint 检测时,要忽略掉这些目录。
build/*
dist/*
node_modules/*
eslint配置文件 .eslintrc.js
module.exports = {
root: true,
parser: 'babel-eslint',
parserOptions: {
sourceType: 'module'
},
// https://github.com/feross/standard/blob/master/RULES.md#javascript-standard-style
extends: ['standard'],
// required to lint *.vue files
plugins: ['vue', 'html'],
// add your custom rules here
'rules': {
// allow paren-less arrow functions
'arrow-parens': 0,
// allow async-await
'generator-star-spacing': 0,
// allow debugger during development
'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0
}
}
3.3 js,jsx文件处理平台 babel 的配置文件 .babelrc
{
"presets": ["es2015", "stage-0", "stage-2"],
"comments": false,
"env": {
"production": {
"plugins": [
["transform-runtime", { "polyfill": false, "regenerator": false }]
]
}
}
}
3.4 编辑 package.json
{
"name": "vue-demo",
"description": "A Vue.js project",
"version": "1.0.0",
"author": "Bing.Rowe <bing.rowe@foxmail.com>",
"private": true,
"scripts": {
"dev": "cross-env NODE_ENV=development webpack-dev-server --open --inline --hot",
"build": "cross-env NODE_ENV=production webpack --progress --hide-modules",
"lint": "eslint --ext .js,.vue src"
},
"dependencies": {
"vue": "^2.1.4"
},
"devDependencies": {
"autoprefixer": "^6.5.3",
"babel-core": "^6.18.2",
"babel-eslint": "^7.1.1",
"babel-loader": "^6.2.8",
"babel-plugin-component": "^0.6.0",
"babel-plugin-transform-runtime": "^6.15.0",
"babel-preset-es2015": "^6.18.0",
"babel-preset-stage-0": "^6.16.0",
"babel-preset-stage-2": "^6.18.0",
"babel-register": "^6.18.0",
"babel-runtime": "^6.18.0",
"clean-webpack-plugin": "^0.1.14",
"copy-webpack-plugin": "^4.0.1",
"cross-env": "^3.1.3",
"css-loader": "^0.26.0",
"eslint": "^3.11.1",
"eslint-config-standard": "^6.2.1",
"eslint-config-vue": "^2.0.1",
"eslint-friendly-formatter": "^2.0.6",
"eslint-loader": "^1.6.1",
"eslint-plugin-flow-vars": "^0.5.0",
"eslint-plugin-html": "^1.7.0",
"eslint-plugin-promise": "^3.4.0",
"eslint-plugin-standard": "^2.0.1",
"eslint-plugin-vue": "^1.0.0",
"extract-text-webpack-plugin": "^2.0.0-beta.4",
"file-loader": "^0.9.0",
"html-webpack-plugin": "^2.24.1",
"image-webpack-loader": "^3.0.0",
"json-loader": "^0.5.4",
"postcss-loader": "^1.1.1",
"style-loader": "^0.13.1",
"url-loader": "^0.5.7",
"vue-html-loader": "^1.2.3",
"vue-loader": "^10.0.2",
"vue-style-loader": "^1.0.0",
"vue-template-compiler": "^2.1.4",
"webpack": "^2.1.0-beta.27",
"webpack-dev-server": "^2.1.0-beta.12"
}
}
-
npm run dev
启动本地服务器,运行项目 -
npm run build
打包项目,输出到dist目录 -
npm run lint
代码检查
3.5 .gitignore
.DS_Store
node_modules/
dist/
npm-debug.log
3.6 使用EditorConfig来规范缩进风格,缩进大小,tab长度以及字符集等
很多开发工具中都可找到editconfig的插件,在项目的根目录创建 .editorconfig
root = true
[*]
charset = utf-8
indent_style = space
indent_size = 2
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
四、写代码
目录结构
| App.vue
| main.js
| main.tpl
\---assets
logo.png
4.1 HTML模板文件 ./src/main.tpl
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="utf-8">
<title>DEMO</title>
</head>
<body><div id="app"></div></body>
</html>
4.2 入口文件 main.js
import Vue from 'vue'
import App from './App.vue'
/* eslint-disable no-new */
new Vue({
el: '#app',
render: h => h(App)
})
4.3 App.vue
<template>
<div id="app">
<img src="./assets/logo.png">
<h1>{{ msg }}</h1>
<h2>Essential Links</h2>
<ul>
<li><a href="https://vuejs.org" target="_blank">Core Docs</a></li>
<li><a href="https://forum.vuejs.org" target="_blank">Forum</a></li>
<li><a href="https://gitter.im/vuejs/vue" target="_blank">Gitter Chat</a></li>
<li><a href="https://twitter.com/vuejs" target="_blank">Twitter</a></li>
</ul>
<h2>Ecosystem</h2>
<ul>
<li><a href="http://router.vuejs.org/" target="_blank">vue-router</a></li>
<li><a href="http://vuex.vuejs.org/" target="_blank">vuex</a></li>
<li><a href="http://vue-loader.vuejs.org/" target="_blank">vue-loader</a></li>
<li><a href="https://github.com/vuejs/awesome-vue" target="_blank">awesome-vue</a></li>
</ul>
</div>
</template>
<script>
export default {
name: 'app',
data () {
return {
msg: 'Welcome to Your Vue.js App'
}
}
}
</script>
<style>
#app {
font-family: 'Avenir', Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
h1, h2 {
font-weight: normal;
}
ul {
list-style-type: none;
padding: 0;
}
li {
display: inline-block;
margin: 0 10px;
}
a {
color: #42b983;
}
</style>
npm run dev
查看演示页面吧。
<END>