个性化构建结果 - vue.config.js
在基础的配置上,自定义构建的结果 - 可以使用 vue.config.js
文档地址:cli.vuejs.org/zh/config/#...
PublicPath
-
PublicPath - 部署应用包时的基本 URL, 这个配置对应的是 webpack 的 PublicPath 属性
- 默认值为 '/' ,Vue CLI 会假设你的应用是被部署在一个域名的根路径上 abc.com/
- 可以设置为子路径 - 如果你的应用被部署在 abc.com/sub/ 那么就设置为 '/sub'
- 可以设置为 CDN 路径 - 在我们的应用中,最后静态资源是要全部上传到 CDN 的,(脚手架自动完成),所以这里可以设置为一个 CDN 域名 - 'oss.imooc-lego.com/editor'
- 还可以设置为绝对路径('' 或者 './'),这样所有的资源都会被链接为相对路径
js
const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
transpileDependencies: true,
publicPath: process.env.NODE_ENV === 'production' ? 'https://oss.imooc-lego.com/editor' : '/'
})
打包之后:
html
<!doctype html>
<html lang="">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1">
<link rel="icon" href="https://oss.imooc-lego.com/editor/favicon.ico">
<title>project</title>
<script defer="defer" src="https://oss.imooc-lego.com/editor/js/chunk-vendors.1f898ac5.js"></script>
<script defer="defer" src="https://oss.imooc-lego.com/editor/js/app.c1aa142b.js"></script>
<link href="https://oss.imooc-lego.com/editor/css/app.2cf79ad6.css" rel="stylesheet">
</head>
<body><noscript><strong>We're sorry but project doesn't work properly without JavaScript enabled. Please enable it to
continue.</strong></noscript>
<div id="app"></div>
</body>
</html>
css.loaderOptions 属性
向 CSS 相关的 loader 传递选项
Ant-design-vue 的样式变量:www.antdv.com/docs/vue/cu...
github.com/vueComponen...
添加更多的 CSS 预处理器:cli.vuejs.org/zh/guide/cs...
特别注意 less 和 less-loader 的版本问题。不要装最新的,建议选用:
js
"less": "^3.12.0",
"less-loader": "^7.1.0"
js
module.exports = {
// 生产环境要使用 OSS 地址
// 其他环境都使用绝对路径
publicPath: (isProduction && !isStaging) ? 'https://oss.imooc-lego.com/' : '',
css: {
loaderOptions: {
less: {
lessOptions: {
modifyVars: {
'primary-color': '#3E7FFF',
},
javascriptEnabled: true
}
}
}
}
}
bundle 打包分析工具
webpack-bundle-analyzer - www.npmjs.com/package/web...
js
const { defineConfig } = require('@vue/cli-service')
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
module.exports = defineConfig({
transpileDependencies: true,
publicPath: process.env.NODE_ENV === 'production' ? 'https://oss.imooc-lego.com/editor' : '/',
configureWebpack: (config) => {
if (process.env.NODE_ENV === 'production') {
config.plugins.push(new BundleAnalyzerPlugin({
analyzerMode: 'static'
}))
}
}
})
- 看看有没有什么重复的模块,或者没有用的模块被打包到了最终的代码中
- 看看 package.json,对比一下是否有应该在 devDeps 的模块,被错误的放置到了 deps 当中
- 检查是否有重复加载的模块,或者是功能大体相同的模块。
- 使用 ** es ** 版本的第三方库,享受 tree - shaking 的红利。
- 检查是否有没有用的模块是否打包到了最终的文件中。
- 使用 webpack ignore plugin webpack.js.org/plugins/ign...
js
configureWebpack: config => {
config.plugins.push(
new webpack.IgnorePlugin({
resourceRegExp: /^./locale$/,
contextRegExp: /moment$/,
})
)
// 打包后资源分析
if (isAnalyzeMode) {
config.plugins.push(
new BundleAnalyzerPlugin({
analyzerMode: 'static',
})
)
}
}
resourceRegExp: /^./locale$/
:表示要忽略的资源(模块路径)匹配以 ./locale
开头的模式。在这里,是为了忽略 moment
库中的 locale
(语言 locale 相关)模块,因为很多情况下我们可能不需要 moment
库自带的所有语言 locale 文件,忽略它们可以减小打包体积。
contextRegExp: /moment$/
:表示要忽略的模块所在的上下文(即模块所在的目录等相关匹配),这里匹配 moment
相关的上下文,结合 resourceRegExp
,就是在 moment
相关的模块中,忽略 ./locale
相关的模块。
按需加载第三方组件库
- 全局引入的方式
js
import Antd from 'ant-design-vue'
app.use(Antd).use(LegoBricks).use(router).use(store)
app.mount('#app')
- 按需引入
configAntD.ts
js
import { Button, Input, InputNumber, Slider, Radio, Select } from 'ant-design-vue'
import { App } from 'vue'
const components = [
Button, Input, InputNumber, Slider, Radio, Select
]
const install = (app: App) => {
components.forEach(component => {
app.component(component.name, component)
})
}
export default {
install
}
vender 拆分

- 充分利用浏览器的缓存
- 浏览器支持平行加载多个文件
- HTTP1 对同一域名并行加载的个数限制
- HTTP2 完全突破这个限制
配置代码:
js
const { defineConfig } = require('@vue/cli-service')
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
module.exports = defineConfig({
transpileDependencies: true,
publicPath: process.env.NODE_ENV === 'production' ? 'https://oss.imooc-lego.com/editor' : '/',
configureWebpack: (config) => {
if (process.env.NODE_ENV === 'production') {
config.plugins.push(new BundleAnalyzerPlugin({
analyzerMode: 'static'
}))
}
config.optimization.splitChunks = {
maxInitialRequests: Infinity,
minSize: 0,
chunks: 'all',
cacheGroups: {
antVendor: {
name: 'ant-design-vue',
test: /[\\/]node_modules[\\/](ant-design-vue)[\\/]/,
},
canvasVendor: {
test: /[\\/]node_modules[\\/](html2canvas)[\\/]/,
name: 'html2canvas'
},
vendor: {
name: 'vendor',
test: /[\\/]node_modules[\\/](!html2canvas)(!ant-design-vue)[\\/]/
}
}
}
}
})
按照大小拆分
js
config.optimization.splitChunks = {
maxInitialRequests: Infinity,
minSize: 300 * 1024,
chunks: 'all',
cacheGroups: {
antVendor: {
test: /[\/]node_modules[\/]/,
name(module) {
const packageName = module.context.match(/[\/]node_modules[\/](.*?)([\/]|$)/)[1];
return `npm.${packageName.replace('@', '')}`;
}
}
}
};
路由懒加载
js
[
{
path: '/editor/:id',
name: 'editor',
component: () => import(/* webpackChunkName: "editor" */ '../views/EditorView.vue'),
meta: { requiredLogin: true, title: '编辑我的设计' }
},
{
path: '/login',
name: 'login',
component: () => import(/* webpackChunkName: "login" */ '../views/LoginView.vue'),
meta: { redirectAlreadyLogin: true, title: '登录到慕课乐高', disableLayout: true }
}
]
使用效果: