虽然Vue CLI可以快速生成项目,但是对于企业需要扩展特定的功能变得极其复杂,并不适合定制化的开发,所以企业中通常是开发人员自己通过构建工具去配置打包项目。下面演示Vue工程的配置代码。

webpack配置分为了4个:公共的以base命名,开发环境的以dev命名,生产环境的以pro命名,以dll命名的是称为动态连接库是提高打包速度用。
上来直接撸代码,我就不再具体介绍哪个loader怎么用了,因为npm官网介绍的比我还清楚。
// webpack.base.conf.js
const path = require('path')
const webpack = require('webpack')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const AddAssetHtmlPlugin = require('add-asset-html-webpack-plugin')
const ProgressBarPlugin = require('progress-bar-webpack-plugin')
const VueLoaderPlugin = require('vue-loader/lib/plugin')
const dir = process.cwd()
module.exports = {
entry: {
app: path.resolve(dir, 'src/main.js')
},
resolve: {
extensions: [
'.js', '.vue', '.less', '.css'
],
alias: {
'src': path.resolve(dir, 'src')
}
},
module: {
rules: [
{
test: /\.(jsx?|babel|es6)$/,
include: dir,
exclude: /node_modules/,
loader: 'babel-loader'
},
{
test: /\.vue$/,
loader: 'vue-loader',
options: {
compilerOptions: {
preserveWhitespace: false
}
}
}
]
},
plugins: [
new HtmlWebpackPlugin({
template: path.resolve(dir, 'template.html'),
chunks: ['app']
}),
new webpack.DllReferencePlugin({
manifest: path.resolve(dir, 'manifest.json')
}),
new AddAssetHtmlPlugin({ filepath: path.resolve(dir, 'dist/vendor.dll.js') }),
new ProgressBarPlugin(),
new VueLoaderPlugin()
]
}
// webpack.dev.conf.js
const webpack = require('webpack')
const path = require('path')
const Merge = require('webpack-merge')
const dir = process.cwd()
const baseConfig = require('./webpack.base.conf')
module.exports = Merge(baseConfig, {
mode: 'development',
output: {
filename: 'js/[name]_[hash].js',
path: path.resolve(dir, 'dist')
},
devtool: 'source-map',
plugins: [
new webpack.DefinePlugin({
NODE_ENV: JSON.stringify('development')
})
],
module: {
rules: [
{
enforce: 'pre',
test: /\.vue$/,
loader: 'eslint-loader',
exclude: /node_modules/,
include: path.resolve(dir, 'src'),
options: {
formatter: require('eslint-friendly-formatter'),
cache: true,
emitWarning: true,
emitError: true
}
},
{
test: /\.(png|svg|jpe?g)$/i,
loader: 'url-loader',
options: {
esModule: false
}
},
{
test: /\.(woff|woff2|eot|ttf|otf)$/i,
loader: 'file-loader',
options: {
esModule: false
}
},
{
test: /\.(css|less)$/,
use: [
{
loader: 'style-loader',
options: {}
},
{
loader: 'css-loader',
options: {
sourceMap: true
}
},
{
loader: 'less-loader',
options: {
sourceMap: true
}
}
]
}
]
},
devServer: {
host: 'localhost',
port: 8000,
hot: true,
open: true,
overlay: {
errors: true,
warnings: true
},
contentBase: path.resolve(dir, 'dist')
},
cache: true
})
在这里提一句关于动态连接库的事情,动态连接库就是把一些不会更改的包进行提前打包,之后再打包就会建立引用关系,就直接引用之前打好的包,不再进行二次打包了。
// webpack.dll.conf.js
const webpack = require('webpack')
const path = require('path')
const dir = process.cwd()
module.exports = {
mode: 'production',
entry: {
vendor: ['vue', 'vuex', 'vue-router']
},
output: {
library: 'familybucket',
filename: '[name].dll.js'
},
plugins: [
new webpack.DllPlugin({
name: 'familybucket',
path: path.resolve(dir, 'manifest.json')
})
]
}
// webpack.pro.conf.js
const webpack = require('webpack')
const path = require('path')
const Merge = require('webpack-merge')
const dir = process.cwd()
const baseConfig = require('./webpack.base.conf')
const {CleanWebpackPlugin} = require('clean-webpack-plugin')
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
module.exports = Merge(baseConfig, {
optimization: {
minimizer: [
new OptimizeCSSAssetsPlugin(),
new UglifyJsPlugin()
]
},
mode: 'production',
output: {
filename: 'js/[name]_[hash].js',
path: path.resolve(dir, 'dist')
},
module: {
rules: [
{
test: /\.(png|svg|jpe?g)$/,
loader: 'url-loader',
options: {
limit: 8192,
name: 'img/[name].[hash:7].[ext]',
publicPath: '/',
esModule: false
}
},
{
test: /\.(woff|woff2|eot|ttf|otf)$/,
loader: 'file-loader',
options: {
name: 'fonts/[name].[hash:7].[ext]',
esModule: false
}
},
{
test: /\.(css|less)$/,
loaders: [
{
loader: MiniCssExtractPlugin.loader,
options: {
insertAt: 'top'
}
},
{
loader: 'css-loader',
options: { importLoaders: 2 }
},
'postcss-loader',
'less-loader'
]
}
]
},
devtool: 'cheap-source-map',
plugins: [
new webpack.DefinePlugin({
NODE_ENV: JSON.stringify('production')
}),
new CleanWebpackPlugin({
cleanOnceBeforeBuildPatterns: ['**/*', '!vendor.dll.js']
}),
new MiniCssExtractPlugin({
filename: 'css/[name].[hash:7].css'
})
]
babel的配置是通过单独增加.babelrc文件
{
"presets": ["@babel/preset-env"],
"plugins": [
[
"@babel/plugin-transform-runtime",
{
"corejs": 3,
"helpers": true,
"regenerator": true,
"useESModules": false
}
],
"@babel/plugin-proposal-class-properties"
]
}
postcss配置是通过单独增加postcss.config.js文件,postcss-preset-env是给CSS样式加前缀的,cssnano是去除多余的CSS的。
module.exports = ({ env }) => ({
parser: false,
plugins: {
'postcss-preset-env': env === 'development' ? false : {},
'cssnano': env === 'development' ? false: {}
}
})
eslint的配置通过单独增加.eslintrc.js文件,这个配置文件可以通过eslint --init进行生成,然后进行定制化配置自己的规则。
module.exports = {
"env": {
"node": true,
"es6": true
},
"extends": [
"eslint:recommended",
"plugin:vue/essential"
],
"globals": {
"Atomics": "readonly",
"SharedArrayBuffer": "readonly"
},
"parserOptions": {
"ecmaVersion": 2020,
"sourceType": "module"
},
"plugins": [
"vue"
],
"rules": {
"indent": ["error", 2],
"space-before-function-paren": ["error", "always"],
"quotes": ["error", 'single']
}
};
这些配置已经完成了常用的开发功能,大家可自行扩展,需要代码链接请点击查看源码查看更多!