携手创作,一起成长!这是我参加「日新方案 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
}
}
});
}
}
};