搭建背景:webpack5正式版已经发布有一段时间了,但vue-cli还是有webpack4,这样导致webpack5的新功能不能发挥,特别是摇树,缓存等功能
项目目录结构
src
├── assets(静态资源)
├── style(样式文件)
├── utils(公共函数目录)
├── views(vue页面目录)
├── App.vue
├── index.html(模板文件)
├── index.js(入口文件)
复制代码
搭建步骤
-
搭建基础配置
- 添加入口,出口配置
const { resolve } = require("path") module.exports = { entry: resolve(__dirname, 'src/index.js'), output: { filename: '[name][contenthash:8].js', path: resolve(__dirname, 'dist'), clean: true, }, } 复制代码
- 添加html模板解析
const { resolve } = require("path") module.exports = { plugins:[ new HtmlWebpackPlugin({ template: resolve(__dirname, 'src/index.html'), //<title><%=htmlWebpackPlugin.options.title %></title> //注意htmlWebpackPlugin首写字母小写 title: "webpack5-vue" }), ] } 复制代码
- 添加资源解析
module.exports = { module: { rules: [ /**webpack5合成了资源模块,会自动处理图片,字体等等资源文件, * 因此不需要使用loader */ { test: /\.(jpe?g|png|gif|svg)$/i, type: 'asset', parser: { dataUrlCondition: { maxSize: 4 * 1024 // 4kb } }, generator: { //单独修改生成路径 filename: 'img/[hash:8][ext][query]' } }, { test: /\.(ttf|woff2)$/i, type: 'asset', generator: { //单独修改生成路径 filename: 'font/[hash:8][ext][query]' } }, ] }, } 复制代码
- 添加引用解析
const { resolve } = require("path") module.exports = { resolve: { alias: { '@': resolve(__dirname, 'src'), } } } 复制代码
- 添加vue-loader
const { VueLoaderPlugin } = require('vue-loader') module.exports = { module: { rules: [ { test: /\.vue$/i, loader: 'vue-loader' }, ] } plugins:[ new VueLoaderPlugin(), ] } 复制代码
-
搭建开发环境
const { resolve } = require("path")
const { merge } = require("webpack-merge")
const base = require("./webpack.base")
const cssLoader = ['vue-style-loader', 'css-loader']
//通过webpack-merge合并基础配置
module.exports = merge(base,{
mode: "development",
module: {
rules: [
{
test: /\.css$/i,
use: cssLoader,
},
{
test: /\.scss$/i,
use: [...cssLoader, 'sass-loader']
},
{
test: /\.(js|vue)$/i,//添加eslint检查
enforce: 'pre',//强制优先允许,防止与babel发生冲突
exclude: /node_modules/,
loader: 'eslint-loader',//eslint-loader配置请查看后方.eslintrc.js文件
options: {
fix: true//自定修复语法错误
}
},
]
},
devtool: 'eval-cheap-module-source-map',
devServer: {
compress: true,
static: {
directory: resolve(__dirname, 'dist'),
},
liveReload: true,//启用热更新
},
target: "web",//启用热更新需配置target:"web"
cache: true,
resolve: {
alias: {
//解析import Vue from 'vue'时,查找vue的路径
vue$: resolve(__dirname, 'node_modules/vue/dist/vue.esm.js'),
}
},
})
复制代码
- 搭建发布环境
const { resolve } = require("path")
const { merge } = require("webpack-merge")
const base = require("./webpack.base")
const MiniCssExtractPlugin = require("mini-css-extract-plugin")
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");
const cssLoader = [MiniCssExtractPlugin.loader, 'css-loader', {
loader: 'postcss-loader',//css自动兼容
options: {
postcssOptions: {
plugins: [
[
'postcss-preset-env',
{
// 其他选项
},
],
]
}
}
}]
module.exports = merge(base, {
mode: "production",
output: {
environment: {
//不要使用箭头模式,兼容IE9
arrowFunction: false
},
//统一修改资源生成路径
assetModuleFilename: 'assets/[hash:8][ext][query]',
},
module: {
rules: [
{
test: /\.js$/i,
exclude: /node_modules/,
use: [{
loader: 'babel-loader',
/**
* package.json配置
* "browserslist": [
"> 1%",
"last 2 versions",
"not ie <= 8"
]
*/
//可以将配置单独抽离到.babelrc文件
options: {
cacheDirectory: true,
presets: [
[
"@babel/preset-env",
{
modules: false,
useBuiltIns: "usage",
corejs: 3
}
]
]
}
}],
},
{
test: /\.css$/i,
use: cssLoader,
},
{
test: /\.scss$/i,
use: [...cssLoader, 'sass-loader']
},
]
},
// devtool:'none',
plugins: [
new MiniCssExtractPlugin({
filename: 'style/[name][contenthash:8].css'
}),
],
resolve: {
alias: {
vue$: resolve(__dirname, 'node_modules/vue/dist/vue.min.js')
}
},
optimization: {
//sideEffects:true要配合package.json的sideEffect字段使用,
//package.json的sideEffect配置如下:true 所有代码都有副作用(不要删除),false(都可以删除),数组(那些文件不要删除)
//sideEffects开启后,样式被去掉解决方法:
//1. 其实我们可以使用require的方式,动态的引入css样式,从而避免被tree shaking摇掉。require('./style.css')
//2. 对css文件不做tree shaking,在package.json的sideEffect中加入数组,[ “*.css” ],不对css文件进行tree shaking。[推荐]
sideEffects: true,//tree shaking Commonjs也支持了
// minimize:true,
minimizer: [
`...`,//保留默认配置,否则js不压缩
new CssMinimizerPlugin(),//压缩css
],
splitChunks: {//chunk切割,提取公共代码,减小主包大小
// include all types of chunks
chunks: 'all',
cacheGroups: {
vue: {
name: 'chunk-vue',
test: /[\\/]node_modules[\\/](vue|vuex|vue-router)[\\/]/,
chunks: 'all',
priority: -10
},
elementUi: {
name: 'chunk-element-ui',
test: /[\\/]node_modules[\\/]element-ui[\\/]/,
chunks: 'all',
priority: -9
}
}
},
},
})
复制代码
-
.eslintrc.js配置
1.通过命令npx eslint --init 生成.eslintrc.js配置,选择支持vuejs,运行环境选择node,自动生成配置文件
module.exports = {
"env": {
"es2021": true,
"node": true
},
"extends": [
"eslint:recommended",
"plugin:vue/essential",
],
"parserOptions": {
"ecmaVersion": 12,
"sourceType": "module"
},
"plugins": [
"vue"
],
};
复制代码
2.添加 eslint-config-airbnb-bas规则
"extends": [
"eslint:recommended",
"plugin:vue/essential",
"airbnb-base"
],
复制代码
3.添加自有规则
"rules": {
"no-console": process.env.NODE_ENV === "production" ? "warn" : "off",
'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
'import/no-unresolved': [
'off',
{
ignore: ['^@/'], // @ 是设置的路径别名
},
],
"semi": ["error", "never"],//分号
"quotes": ["error", "single"],//字符串“”
}
复制代码