携手创作,一起成长!这是我参加「日新方案 8 月更文挑战」的第1天
前段时间,对部分的个别项目进行
Vue3.0+ts框架的搬迁,刚开始研讨的时分也是踩坑特别多,特别咱们的项目还有些特别的webpack装备,所以,研讨vue.config.js的装备的时分也是查阅了各种资料文档,终究,完结了项目webpack的特别装备。
今天分享一下,咱们项目傍边的一些webpack装备,希望能给咱们有所启示;只要装备多了,你就会发现其实一切的装备的都是类似的,特别像插件的装备,都是十分类似的。
咱们现在开始进入今天的主题啦~~
1 介绍
之前,我有提到过,当然咱们肯定也都知道,Vue3.0不在有webpack.config.js的装备;但是不可避免,在项目开发中咱们肯定会存在一些特别的需求需求调整webpack, 这个时分,在Vue3.0的项目傍边,咱们就需求在根目录创立vue.config.js去完结webpack的一些特别装备,默许它会被@vue/cli-service主动加载。
此刻,你需求创立vue.config.js文件。
查看默许的webpack装备
Vue CLI 官方文档:
vue-cli-service暴露了inspect指令用于审查解析好的webpack装备。那个大局的 vue 可执行程序相同供给了inspect指令,这个指令仅仅简略的把vue-cli-service``inspect代理到了你的项目中。
被抽象化的webpack,咱们要想去理解它默许的一些装备的话是比较困难的,所以咱们能够经过指令去查看。
该指令会将webpack的装备输出到output.js文件,这样方便去查看。
vue inspect > output.js
仿制代码
vue.config.js文件
这个文件导出了一个包含了选项的对象:
module.exports = {
// 选项...
}
仿制代码
接下来,具体介绍一些选项及装备:
2 根本装备
module.exports = {
productionSourceMap: false,
publicPath: './',
outputDir: 'dist',
assetsDir: 'assets',
devServer: {
port: 8090,
host: '0.0.0.0',
https: false,
open: true
},
// 其他装备
...
仿制代码
-
productionSourceMap:生产环境是否要生成
sourceMap -
publicPath:部署运用包时的根本 URL,用法和
webpack自身的output.publicPath一致- 能够经过三元运算去装备
dev和prod环境,publicPath: process.env.NODE_ENV === 'production' ? '/prod/' : './'
- 能够经过三元运算去装备
-
outputDir:
build时输出的文件目录 -
assetsDir: 放置静态文件夹目录
-
devServer: dev环境下,
webpack-dev-server相关装备- port: 开发运转时的端口
-
host: 开发运转时域名,设置成
'0.0.0.0',在同一个局域网下,假如你的项目在运转,同时能够经过你的http://ip:port/...访问你的项目 -
https: 是否启用
https -
open:
npm run serve时是否直接翻开浏览器
3 插件及规则的装备
在vue.config.js假如要新增/修正webpack的plugins或者rules, 有2种办法。
configureWebpack办法
configureWebpack 是相对比较简略的一种办法
- 它能够是一个
对象:和webpack自身装备办法是一致,该对象将会被webpack-merge合并入终究的webpack装备 - 它也能够是一个
函数:直接在函数内部进行修正装备
configureWebpack: {
rules:[],
plugins: []
}
configureWebpack: (config) => {
// 例如,经过判别运转环境,设置mode
config.mode = 'production'
}
仿制代码
chainWebpack办法
chainWebpack 链式操作 (高档),接下来一切的装备我都会在该选项中进行装备
4 规则rules的装备
关于rules的装备,我会分别从新增/修正进行介绍。
4.1 rules的新增
在webpack中rules是module的装备项,而一切的装备的都是挂载到config下的,所以新增一个rule办法:
config.module
.rule(name)
.use(name)
.loader(loader)
.options(options)
仿制代码
事例:style-resources-loader来增加less大局变量
事例:svg-sprite-loader将svg图片以雪碧图的办法在项目中加载
module.exports = {
chainWebpack: (config) => {
// 经过 style-resources-loader 来增加less大局变量
const types = ['vue-modules', 'vue', 'normal-modules', 'normal'];
types.forEach(type => {
let rule = config.module.rule('less').oneOf(type)
rule.use('style-resource')
.loader('style-resources-loader')
.options({
patterns: [path.resolve(__dirname, './lessVariates.less')]
});
});
// `svg-sprite-loader`: 将svg图片以雪碧图的办法在项目中加载
config.module
.rule('svg')
.test(/.svg$/) // 匹配svg文件
.include.add(resolve('src/svg')) // 主要匹配src/svg
.end()
.use('svg-sprite-loader')
.loader('svg-sprite-loader') // 运用的loader,主要要npm该插件
.options({symbolId: 'svg-[name]'}) // 参数装备
}
}
仿制代码
4.2 rules的修正
针对现已存在的rule, 假如需求修正它的参数, 能够运用tap办法:
config.module
.rule(name)
.use(name)
.tap(options => newOptions)
仿制代码
事例:修正url-loader的参数
module.exports = {
chainWebpack: (config) => {
// `url-loader`是webpack默许现已装备的,现在咱们来修正它的参数
config.module.rule('images')
.use('url-loader')
.tap(options => ({
name: './assets/images/[name].[ext]',
quality: 85,
limit: 0,
esModule: false,
}))
}
}
仿制代码
5 插件plugins 的装备
关于plugins的装备,我会分别从新增/修正/删去进行介绍。
5.1 plugins的新增
- 留意:这儿WebpackPlugin不需求经过
new WebpackPlugin()运用。
config
.plugin(name)
.use(WebpackPlugin, args)
仿制代码
事例:新增hot-hash-webpack-plugin
const HotHashWebpackPlugin = require('hot-hash-webpack-plugin');
module.exports = {
chainWebpack: (config) => {
// 新增一个`hot-hash-webpack-plugin`
// 留意:这儿use的时分不需求运用`new HotHashWebpackPlugin()`
config.plugin('hotHash')
.use(HotHashWebpackPlugin, [{ version: '1.0.0' }]);
}
}
仿制代码
5.2 plugins的修正
同理,plugin参数的修正也是经过tap去修正。
config
.plugin(name)
.tap(args => newArgs)
仿制代码
事例:修正打包后css抽离后的filename及抽离所属目录
事例:删去console和debugger
const HotHashWebpackPlugin = require('hot-hash-webpack-plugin');
module.exports = {
chainWebpack: (config) => {
// 修正打包时css抽离后的filename及抽离所属目录
config.plugin('extract-css')
.tap(args => [{
filename: 'css/[name].[contenthash:8].css',
chunkFilename: 'css/[name].[contenthash:8].css'
}]);
// 正式环境下,删去console和debugger
config.optimization
.minimize(true)
.minimizer('terser')
.tap(args => {
let { terserOptions } = args[0];
terserOptions.compress.drop_console = true;
terserOptions.compress.drop_debugger = true;
return args
});
}
}
仿制代码
5.3 plugins的删去
关于一些webpack默许的plugin,假如不需求能够进行删去
config.plugins.delete(name)
仿制代码
事例:删去vue-cli3.X模块的主动切割抽离
module.exports = {
chainWebpack: (config) => {
// vue-cli3.X 会主动进行模块切割抽离,假如不需求进行切割,能够手动删去
config.optimization.delete('splitChunks');
}
}
仿制代码
6 一些常见的装备
6.1 修正enter文件
webpack默许的entry入口是scr/main.ts
config.entryPoints.clear(); // 清空默许入口
config.entry('test').add(getPath('./test/main.ts')); // 重新设置
仿制代码
6.2 DefinePlugin
界说大局大局变量,DefinePlugin是webpack现已默许装备的,咱们能够对参数进行修正
config.plugin('define').tap(args => [{
...args,
"window.isDefine": JSON.stringify(true),
}]);
仿制代码
6.3 自界说filename 及 chunkFilename
自界说打包后js文件的路径及文件名字
config.output.filename('./js/[name].[chunkhash:8].js');
config.output.chunkFilename('./js/[name].[chunkhash:8].js');
仿制代码
6.4 修正html-webpack-plugin参数
html-webpack-plugin是webpack现已默许装备的,默许的源模版文件是public/index.html;咱们能够对其参数进行修正
config.plugin('html')
.tap(options => [{
template: '../../index.html' // 修正源模版文件
title: 'test',
}]);
仿制代码
6.5 设置别号alias
webpack默许是将src的别号设置为@, 此外,咱们能够进行增加
config.resolve.alias
.set('@', resolve('src'))
.set('api', resolve('src/apis'))
.set('common', resolve('src/common'))
仿制代码
7 附上一份我的vue.config.js的装备
const path = require('path');
const HotHashWebpackPlugin = require('hot-hash-webpack-plugin');
const WebpackBar = require('webpackbar');
const resolve = (dir) => path.join(__dirname, '.', dir);
module.exports = {
productionSourceMap: false,
publicPath: './',
outputDir: 'dist',
assetsDir: 'assets',
devServer: {
port: 9999,
host: '0.0.0.0',
https: false,
open: true
},
chainWebpack: (config) => {
const types = ['vue-modules', 'vue', 'normal-modules', 'normal'];
types.forEach(type => {
let rule = config.module.rule('less').oneOf(type)
rule.use('style-resource')
.loader('style-resources-loader')
.options({
patterns: [path.resolve(__dirname, './lessVariates.less')]
});
});
config.resolve.alias
.set('@', resolve('src'))
.set('api', resolve('src/apis'))
.set('common', resolve('src/common'))
config.module.rule('images').use('url-loader')
.tap(options => ({
name: './assets/images/[name].[ext]',
quality: 85,
limit: 0,
esModule: false,
}));
config.module.rule('svg')
.test(/.svg$/)
.include.add(resolve('src/svg'))
.end()
.use('svg-sprite-loader')
.loader('svg-sprite-loader');
config.plugin('define').tap(args => [{
...args,
"window.isDefine": JSON.stringify(true)
}]);
// 生产环境装备
if (process.env.NODE_ENV === 'production') {
config.output.filename('./js/[name].[chunkhash:8].js');
config.output.chunkFilename('./js/[name].[chunkhash:8].js');
config.plugin('extract-css').tap(args => [{
filename: 'css/[name].[contenthash:8].css',
chunkFilename: 'css/[name].[contenthash:8].css'
}]);
config.plugin('hotHash').use(HotHashWebpackPlugin, [{ version : '1.0.0'}]);
config.plugin('webpackBar').use(WebpackBar);
config.optimization.minimize(true)
.minimizer('terser')
.tap(args => {
let { terserOptions } = args[0];
terserOptions.compress.drop_console = true;
terserOptions.compress.drop_debugger = true;
return args
});
config.optimization.splitChunks({
cacheGroups: {
common: {
name: 'common',
chunks: 'all',
minSize: 1,
minChunks: 2,
priority: 1
},
vendor: {
name: 'chunk-libs',
chunks: 'all',
test: /[/]node_modules[/]/,
priority: 10
}
}
});
}
}
};

