feat: ✨ 提供多页面构建示例,优化了打包分包,取消CDN加载依赖但保留了设置入口
This commit is contained in:
219
vue.config.js
219
vue.config.js
@@ -2,49 +2,97 @@ const CompressionWebpackPlugin = require('compression-webpack-plugin')
|
||||
const VueFilenameInjector = require('@d2-projects/vue-filename-injector')
|
||||
const ThemeColorReplacer = require('webpack-theme-color-replacer')
|
||||
const forElementUI = require('webpack-theme-color-replacer/forElementUI')
|
||||
const cdnDependencies = require('./dependencies-cdn')
|
||||
const { chain, set, each } = require('lodash')
|
||||
const { set, each, compact, map, keys } = require('lodash')
|
||||
|
||||
// 拼接路径
|
||||
const resolve = dir => require('path').join(__dirname, dir)
|
||||
|
||||
// 增加环境变量
|
||||
// Add environment variable
|
||||
process.env.VUE_APP_VERSION = require('./package.json').version
|
||||
process.env.VUE_APP_BUILD_TIME = require('dayjs')().format('YYYY-M-D HH:mm:ss')
|
||||
|
||||
// 基础路径 注意发布之前要先修改这里
|
||||
const publicPath = process.env.VUE_APP_PUBLIC_PATH || '/'
|
||||
|
||||
// 设置不参与构建的库
|
||||
const externals = {}
|
||||
cdnDependencies.forEach(pkg => { externals[pkg.name] = pkg.library })
|
||||
|
||||
// 引入文件的 cdn 链接
|
||||
const cdn = {
|
||||
css: cdnDependencies.map(e => e.css).filter(e => e),
|
||||
js: cdnDependencies.map(e => e.js).filter(e => e)
|
||||
// Build configuration for multiple pages
|
||||
const pages = {
|
||||
index: {
|
||||
entry: 'src/main.js',
|
||||
template: 'public/index.html',
|
||||
filename: 'index.html',
|
||||
chunks: [
|
||||
'manifest',
|
||||
'index',
|
||||
'chunk-index',
|
||||
'chunk-vendor',
|
||||
'chunk-common',
|
||||
'chunk-vue',
|
||||
'chunk-element'
|
||||
]
|
||||
},
|
||||
mobile: {
|
||||
entry: 'src.mobile/main.js',
|
||||
template: 'public/mobile.html',
|
||||
filename: 'mobile.html',
|
||||
chunks: [
|
||||
'manifest',
|
||||
'mobile',
|
||||
'chunk-mobile',
|
||||
'chunk-vendor',
|
||||
'chunk-common',
|
||||
'chunk-vue'
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
// 多页配置,默认未开启,如需要请参考 https://cli.vuejs.org/zh/config/#pages
|
||||
const pages = undefined
|
||||
// const pages = {
|
||||
// index: './src/main.js',
|
||||
// subpage: './src/subpage.js'
|
||||
// }
|
||||
// Set up the external dependency package introduced by the method of using CDN
|
||||
// For example
|
||||
// if you set the Axios related link configuration here
|
||||
// Axios will no longer participate in the packaging during the construction. Finally
|
||||
// the external link you configured will be used to import Axios in the build result
|
||||
const cdn = {
|
||||
// Which external dependencies related to index page are introduced in the form of CDN links
|
||||
index: [
|
||||
// {
|
||||
// name: 'axios',
|
||||
// library: 'axios',
|
||||
// js: 'https://cdn.jsdelivr.net/npm/axios@0.19.0/dist/axios.min.js',
|
||||
// css: ''
|
||||
// }
|
||||
],
|
||||
// Which external dependencies related to mobile page are introduced in the form of CDN links
|
||||
mobile: [
|
||||
// {
|
||||
// name: 'axios',
|
||||
// library: 'axios',
|
||||
// js: 'https://cdn.jsdelivr.net/npm/axios@0.19.0/dist/axios.min.js',
|
||||
// css: ''
|
||||
// }
|
||||
]
|
||||
}
|
||||
|
||||
// Set external dependent packages that do not participate in the build
|
||||
const externals = {}
|
||||
keys(pages).forEach(name => {
|
||||
cdn[name].forEach(p => {
|
||||
externals[p.name] = p.library
|
||||
})
|
||||
})
|
||||
|
||||
module.exports = {
|
||||
// 根据你的实际情况更改这里
|
||||
publicPath,
|
||||
publicPath: process.env.VUE_APP_PUBLIC_PATH || '/',
|
||||
lintOnSave: true,
|
||||
devServer: {
|
||||
publicPath, // 和 publicPath 保持一致
|
||||
disableHostCheck: process.env.NODE_ENV === 'development' // 关闭 host check,方便使用 ngrok 之类的内网转发工具
|
||||
publicPath: process.env.VUE_APP_PUBLIC_PATH || '/',
|
||||
disableHostCheck: process.env.NODE_ENV === 'development'
|
||||
},
|
||||
css: {
|
||||
loaderOptions: {
|
||||
// 设置 scss 公用变量文件
|
||||
sass: {
|
||||
prependData: '@import \'~@/assets/style/public.scss\';'
|
||||
},
|
||||
less: {
|
||||
lessOptions: {
|
||||
modifyVars: {
|
||||
blue: '#2262AB'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -66,33 +114,92 @@ module.exports = {
|
||||
}
|
||||
return configNew
|
||||
},
|
||||
// 默认设置: https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-service/lib/config/base.js
|
||||
// default: https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-service/lib/config/base.js
|
||||
chainWebpack: config => {
|
||||
/**
|
||||
* 添加 CDN 参数到 htmlWebpackPlugin 配置中
|
||||
* 已适配多页
|
||||
*/
|
||||
const htmlPluginNames = chain(pages).keys().map(page => 'html-' + page).value()
|
||||
const targetHtmlPluginNames = htmlPluginNames.length ? htmlPluginNames : ['html']
|
||||
each(targetHtmlPluginNames, name => {
|
||||
config.plugin(name).tap(options => {
|
||||
set(options, '[0].cdn', process.env.NODE_ENV === 'production' ? cdn : [])
|
||||
config.optimization.runtimeChunk({
|
||||
name: 'manifest'
|
||||
})
|
||||
config.optimization.splitChunks({
|
||||
cacheGroups: {
|
||||
// External dependencies common to all pages
|
||||
libs: {
|
||||
name: 'chunk-vendor',
|
||||
chunks: 'initial',
|
||||
minChunks: 1,
|
||||
test: /[\\/]node_modules[\\/]/,
|
||||
priority: 1,
|
||||
reuseExistingChunk: true,
|
||||
enforce: true
|
||||
},
|
||||
// Code common to all pages
|
||||
common: {
|
||||
name: 'chunk-common',
|
||||
chunks: 'initial',
|
||||
minChunks: 2,
|
||||
maxInitialRequests: 5,
|
||||
minSize: 0,
|
||||
priority: 2,
|
||||
reuseExistingChunk: true,
|
||||
enforce: true
|
||||
},
|
||||
// External dependencies that are only used by the index page
|
||||
index: {
|
||||
name: 'chunk-index',
|
||||
chunks: 'all',
|
||||
minChunks: 1,
|
||||
test: /[\\/]node_modules[\\/](sortablejs|screenfull|nprogress|hotkeys-js|fuse\.js|better-scroll|lowdb|shortid)[\\/]/,
|
||||
priority: 3,
|
||||
reuseExistingChunk: true,
|
||||
enforce: true
|
||||
},
|
||||
// External dependencies that are only used by the mobile page
|
||||
mobile: {
|
||||
name: 'chunk-mobile',
|
||||
chunks: 'all',
|
||||
minChunks: 1,
|
||||
test: /[\\/]node_modules[\\/](vant)[\\/]/,
|
||||
priority: 3,
|
||||
reuseExistingChunk: true,
|
||||
enforce: true
|
||||
},
|
||||
// Vue family packages
|
||||
vue: {
|
||||
name: 'chunk-vue',
|
||||
test: /[\\/]node_modules[\\/](vue|vue-router|vuex)[\\/]/,
|
||||
chunks: 'all',
|
||||
priority: 3,
|
||||
reuseExistingChunk: true,
|
||||
enforce: true
|
||||
},
|
||||
// only element-ui
|
||||
element: {
|
||||
name: 'chunk-element',
|
||||
test: /[\\/]node_modules[\\/]element-ui[\\/]/,
|
||||
chunks: 'all',
|
||||
priority: 3,
|
||||
reuseExistingChunk: true,
|
||||
enforce: true
|
||||
}
|
||||
}
|
||||
})
|
||||
// Add the CDN settings to the settings of the htmlwebpackplugin plug-in
|
||||
keys(pages).forEach(name => {
|
||||
const packages = cdn[name]
|
||||
config.plugin(`html-${name}`).tap(options => {
|
||||
const setting = {
|
||||
css: compact(map(packages, 'css')),
|
||||
js: compact(map(packages, 'js'))
|
||||
}
|
||||
set(options, '[0].cdn', process.env.NODE_ENV === 'production' ? setting : [])
|
||||
return options
|
||||
})
|
||||
})
|
||||
|
||||
/**
|
||||
* 删除懒加载模块的 prefetch preload,降低带宽压力
|
||||
* https://cli.vuejs.org/zh/guide/html-and-static-assets.html#prefetch
|
||||
* https://cli.vuejs.org/zh/guide/html-and-static-assets.html#preload
|
||||
* 而且预渲染时生成的 prefetch 标签是 modern 版本的,低版本浏览器是不需要的
|
||||
*/
|
||||
config.plugins
|
||||
.delete('prefetch')
|
||||
.delete('preload')
|
||||
// 解决 cli3 热更新失效 https://github.com/vuejs/vue-cli/issues/1559
|
||||
config.resolve
|
||||
.symlinks(true)
|
||||
// Remove prefetch preload settings for lazy load modules
|
||||
each(keys(pages), name => {
|
||||
config.plugins.delete(`prefetch-${name}`)
|
||||
config.plugins.delete(`preload-${name}`)
|
||||
})
|
||||
// webpack-theme-color-replacer
|
||||
config
|
||||
.plugin('theme-color-replacer')
|
||||
.use(ThemeColorReplacer, [{
|
||||
@@ -104,11 +211,11 @@ module.exports = {
|
||||
changeSelector: forElementUI.changeSelector
|
||||
}])
|
||||
config
|
||||
// 开发环境 sourcemap 不包含列信息
|
||||
// The development environment sourcemap does not contain column information
|
||||
.when(process.env.NODE_ENV === 'development',
|
||||
config => config.devtool('cheap-source-map')
|
||||
)
|
||||
// 预览环境构建 vue-loader 添加 filename
|
||||
// Add file name
|
||||
.when(
|
||||
process.env.VUE_APP_SCOURCE_LINK === 'TRUE',
|
||||
config => VueFilenameInjector(config, {
|
||||
@@ -142,15 +249,9 @@ module.exports = {
|
||||
.exclude
|
||||
.add(resolve('src/assets/svg-icons/icons'))
|
||||
.end()
|
||||
// 重新设置 alias
|
||||
// set alias
|
||||
config.resolve.alias
|
||||
.set('@api', resolve('src/api'))
|
||||
// 分析工具
|
||||
if (process.env.npm_config_report) {
|
||||
config
|
||||
.plugin('webpack-bundle-analyzer')
|
||||
.use(require('webpack-bundle-analyzer').BundleAnalyzerPlugin)
|
||||
}
|
||||
.set('@.mobile', resolve('src.mobile'))
|
||||
},
|
||||
// 不输出 map 文件
|
||||
productionSourceMap: false,
|
||||
|
||||
Reference in New Issue
Block a user