安装 webpack、vue
npm i webpack webpack-cli -D
npm i vue vue-router -S
在项目根目录创建build文件夹,然后创建3个分别是webpack.base.conf.js、webpack.dev.conf.js、webpack.prod.conf.js文件,存放基础配置与开发、生产环境的配置。
项目目录如下图:
打开src/router/index.js 文件,配置”登录页面“路由:
1 import Vue from 'vue' 2 import VueRouter from 'vue-router' 3 4 Vue.use(VueRouter) 5 6 import login from '../views/login/login.vue' 7 8 export default new VueRouter({ 9 routes: [{ 10 path: '/', 11 name: 'login', 12 component: login, 13 meta: { 14 title: '登录' 15 } 16 }] 17 })
src/index.html添加如下代码:
1 2 3 4 5 6 78 9 10 1113 1412
src/index.js添加如下代码:
1 import Vue from 'vue' 2 import router from './router/index.js' 3 4 new Vue({ 5 el: '#app', 6 router 7 })
src/build/webpack.base.conf.js配置代码如下:
1 const webpack = require('webpack') 2 const path = require('path') 3 const VueLoaderPlugin = require('vue-loader/lib/plugin') 4 const HtmlWebpackPlugin = require('html-webpack-plugin') 5 const MiniCssExtractPlugin = require('mini-css-extract-plugin') 6 7 const isDev = process.env.NODE_ENV === 'production' 8 9 let pluginsConfig = [ 10 new VueLoaderPlugin(), 11 new HtmlWebpackPlugin({ 12 title: 'my App', 13 template: path.join(__dirname, '../src/index.html') 14 }), 15 new webpack.DefinePlugin({ 16 'process.env': { 17 'NODE_ENV': JSON.stringify(process.env.NODE_ENV) 18 } 19 }) 20 ] 21 if (!isDev) { 22 pluginsConfig = pluginsConfig.concat(new MiniCssExtractPlugin({ 23 filename: "css/[name]_[contenthash].css" 24 })) 25 } 26 27 module.exports = { 28 mode: process.env.NODE_ENV || 'production', 29 entry: path.join(__dirname, '../src/index.js'), 30 output: { 31 filename: 'bundle.js', 32 path: path.join(__dirname, '../dist') 33 }, 34 module: { 35 rules: [{ 36 test: /\.vue$/, 37 loader: 'vue-loader' 38 }, 39 { 40 test: /\.scss$/, 41 use: [ 42 isDev ? 'vue-style-loader' : MiniCssExtractPlugin.loader, 43 { 44 loader: 'css-loader', 45 options: { 46 modules: true, 47 localIdentName: '[local]_[hash:base64:8]' 48 } 49 }, 50 'sass-loader' 51 ] 52 }, 53 { 54 test: /\.(png|jpg|gif)$/, 55 loader: 'url-loader?name=images/[name]-[contenthash:5].[ext]&limit=2000' 56 }, { 57 test: /\.js$/, 58 loader: 'babel-loader?cacheDirectory', 59 exclude: '/node_modules/', 60 include: path.resolve(__dirname, '../src') 61 } 62 ] 63 }, 64 plugins: pluginsConfig, 65 resolve: { 66 alias: { 67 'vue$': 'vue/dist/vue.esm.js' 68 } 69 } 70 }
先安装解析.vue文件的loader及vue模版编译器:npm i vue-loader vue-template-compiler -D
参考链接:https://vue-loader.vuejs.org/guide/#manual-configuration、https://vue-loader.vuejs.org/options.html#compileroptions、
https://cn.vuejs.org/v2/guide/installation.html#%E8%BF%90%E8%A1%8C%E6%97%B6-%E7%BC%96%E8%AF%91%E5%99%A8-vs-%E5%8F%AA%E5%8C%85%E5%90%AB%E8%BF%90%E8%A1%8C%E6%97%B6
const VueLoaderPlugin = require('vue-loader/lib/plugin') module:{ rules:[ { test:/\.vue$/, loader:'vue-loader' } ] }, plugins:[ new VueLoaderPlugin() ], resolve:{ alias:{ 'vue$':'vue/dist/vue.esm.js' } }
安装html-webpack-plugin插件:npm i html-webpack-plugin -D
new HtmlWebpackPlugin({ title: 'my App', template: path.join(__dirname, '../src/index.html') })
参考链接:https://github.com/jantimon/html-webpack-plugin#
安装 cross-env (跨平台设置环境变量):npm i cross-env -D
参考链接:https://www.npmjs.com/package/cross-env
使用scss CSS预处理器,安装sass-loader:npm i sass-loader node-sass css-loader vue-style-loader -D
将CSS 提取到单独文件中:npm i mini-css-extract-plugin -D
CSS添加浏览器供应商前缀:npm i postcss-loader autoprefixer -D
const isDev = process.env.NODE_ENV === 'development'
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const pluginsConfig=[]
//生产环境才启用此插件,开发环境启用了,热更新会失效
if(!isDev){
pluginsConfig = pluginsConfig.concat(new MiniCssExtractPlugin({
filename: "css/[name]_[contenthash].css"
}))
}
{ test:/\.scss$/, use:[ isDev?'vue-style-loader': MiniCssExtractPlugin.loader, { loader: 'css-loader', options:{ modules:true, localIdentName: 'purify_[local]_[hash:base64:8]' }
}, { loader: 'postcss-loader', options:{ sourceMap: isDev ? true: false } }, 'sass-loader', ] }
参考链接:https://vue-loader.vuejs.org/guide/pre-processors.html#sass-vs-scss
项目根目录创建postcss.config.js文件,配置如下:
module.exports = { loader: 'postcss-loader', plugins: [ require('autoprefixer') ] }
参考链接:https://github.com/ecmadao/Coding-Guide/blob/master/Notes/CSS/PostCSS%E9%85%8D%E7%BD%AE%E6%8C%87%E5%8C%97.md
处理图片资源:npm i url-loader -D
{ test: /\.(png|jpg|gif)$/, loader: 'url-loader?name=images/[name]-[contenthash:5].[ext]&limit=2000' },
使用babel处理JS文件:npm i @babel/core babel-loader -D
{ test: /\.js$/, loader: 'babel-loader?cacheDirectory', exclude: '/node_modules/', include: path.resolve(__dirname, '../src') }
处理JS新语法变换:npm i @babel/preset-env -S
处理JS新函数:npm i @babel/plugin-transform-runtime -D npm i @babel/runtime -S
删除所有console.*输出:npm i babel-plugin-transform-remove-console -D
在项目根目录创建.babelrc文件,添加代码如下:
{ "presets": [ [ "@babel/preset-env", { "modules": false } ] ], "plugins": [ "@babel/plugin-transform-runtime", [ "transform-remove-console", { "include": ["error", "warn"] } ] ] }
参考链接:https://babeljs.io/docs/en/
src/build/webpack.dev.conf.js配置代码如下:
1 const webpack = require('webpack') 2 const path = require('path') 3 const WebPackBaseConfig = require('./webpack.base.conf.js') 4 const CleanWebpackPlugin = require('clean-webpack-plugin') 5 const WebPackMerge = require('webpack-merge') 6 7 module.exports = WebPackMerge(WebPackBaseConfig, { 8 devtool: 'inline-source-map', 9 devServer: { 10 contentBase: path.join(__dirname, 'dist'), //告诉服务器从哪个目录中提供内容 11 compress: true, //启用 gzip 压缩 12 port: 9000, //端口号 13 host: '0.0.0.0', //默认是 localhost。如果希望服务器外部可访问,则设置为0.0.0.0 14 hot: true //启用热替换模块 必须配置 webpack.HotModuleReplacementPlugin 15 }, 16 plugins: [ 17 new CleanWebpackPlugin(['dist']), //清理文件夹 18 new webpack.HotModuleReplacementPlugin(), //启用热替换模块 19 new webpack.NamedModulesPlugin() //启用HMR时,插件将显示模块的相对路径 20 ] 21 })
开发服务器:npm i webpack-dev-server -D
清理文件夹:npm i clean-webpack-plugin -D
参考链接:https://webpack.docschina.org/guides/development/#%E4%BD%BF%E7%94%A8-webpack-dev-server
https://webpack.docschina.org/guides/output-management/#%E6%B8%85%E7%90%86-dist-%E6%96%87%E4%BB%B6%E5%A4%B9
src/build/webpack.prod.conf.js配置代码如下:
1 const webpack = require('webpack') 2 const path = require('path') 3 const WebPackMerge = require('webpack-merge') 4 const WebPackBaseConfig = require('./webpack.base.conf.js') 5 const UglifyJsPlugin = require('uglifyjs-webpack-plugin') 6 const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin') 7 const glob = require('glob-all') 8 const PurifyCSSPlugin = require('purifycss-webpack') 9 10 module.exports = WebPackMerge(WebPackBaseConfig, { 11 output: { 12 filename: '[name].js', 13 chunkFilename: '[name].[chunkhash:5].js', 14 path: path.resolve(__dirname, 'dist') 15 }, 16 optimization: { 17 splitChunks: { 18 cacheGroups: { 19 commons: { 20 test: /[\\/]node_modules[\\/]/, 21 name: 'vendors', 22 chunks: 'all' 23 } 24 } 25 }, 26 runtimeChunk: true, 27 minimizer: [ 28 new UglifyJsPlugin({ 29 cache: true, 30 parallel: true 31 }), 32 new OptimizeCSSAssetsPlugin() 33 ] 34 }, 35 plugins: [ 36 new PurifyCSSPlugin({ 37 paths: glob.sync([ 38 path.join(__dirname, '../src/') 39 ]), 40 purifyOptions: { 41 whitelist: ['*purify*'] 42 } 43 }), 44 ] 45 })
JS 代码优化:npm i uglifyjs-webpack-plugin -D
optimization:{ minimizer:[ new UglifyJsPlugin({ cache: true, parallel: true }) ] }
参考链接:https://www.npmjs.com/package/uglifyjs-webpack-plugin
CSS 代码优化:npm i optimize-css-assets-webpack-plugin -D
optimization:{ minimizer:[ new OptimizeCSSAssetsPlugin() ] }
参考链接:https://www.npmjs.com/package/optimize-css-assets-webpack-plugin
CSS Tree--shaking:npm i glob-all purify-css purifycss-webpack -D
plugins: [ new PurifyCSSPlugin({ paths: glob.sync([ path.join(__dirname, '../src/') ]), purifyOptions: { whitelist: ['*purify*'] } }), ]
参考链接:https://www.npmjs.com/package/purifycss-webpack
删除文件夹:npm i rimraf -D
package.json scripts配置:
"scripts": { "clean": "rimraf dist", "build": "cross-env NODE_ENV=production webpack --config ./build/webpack.prod.conf.js", "dev": "cross-env NODE_ENV=development webpack-dev-server --config ./build/webpack.dev.conf.js", "start": "npm run clean && npm run build" }
。。。。