1. 修改public/index.html
通过htmlwebpackplugin动态注入脚本和样式,index.html如下:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width,initial-scale=1.0"> <link rel="icon" href="<%= BASE_URL %>favicon.ico" rel="external nofollow" > <title>杭州纳舍科技</title> <!-- 使用CDN的css文件 --> <% for (var i in htmlWebpackPlugin.options.cdn && htmlWebpackPlugin.options.cdn.css) { %> <link href="<%= htmlWebpackPlugin.options.cdn.css[i] %>" rel="external nofollow" rel="external nofollow" rel="preload" as="style"> <link href="<%= htmlWebpackPlugin.options.cdn.css[i] %>" rel="external nofollow" rel="external nofollow" rel="stylesheet"> <% } %> <!-- 使用CDN的JS文件 --> <% for (var i in htmlWebpackPlugin.options.cdn && htmlWebpackPlugin.options.cdn.js) { %> <link href="<%= htmlWebpackPlugin.options.cdn.js[i] %>" rel="external nofollow" rel="preload" as="script"> <% } %> </head> <body> <noscript> <strong>We're sorry but ui doesn't work properly without javascript enabled. Please enable it to continue.</strong> </noscript> <div class="global-loading"> <div class="spinner"></div> </div> <div id="app"></div> <!-- built files will be auto injected --> <% for (var i in htmlWebpackPlugin.options.cdn && htmlWebpackPlugin.options.cdn.js) { %> <script src="<%= htmlWebpackPlugin.options.cdn.js[i] %>"></script> <% } %> </body> </html>
2. 修改vue.config.js配置
首先我们会考虑哪些东西要进行CDN优化,例如我们需要把vue、vue-router、moment
在构建的时候排除在外使用CDN加载这三个库,那么需要把添加externals
const isProduction = process.env.NODE_ENV === 'production'; module.exports = { configureWebpack: config => { if (isProduction) { config.externals = { 'vue': 'Vue', 'vue-router': 'VueRouter', 'moment': 'moment' } } } }
现在我们运行npm run build 打包出来的文件就没有Vue、VueRouter、moment,现在我们使用html-webpack-plugin插件进行动态注入CDN,在vue-cli 3.0 中我们要这样配置:
const isProduction = process.env.NODE_ENV === 'production'; const cdn = { css: ['xxx.css', 'sss.js'], js: ['xxxx.js', 'sss.js'] } module.exports = { configureWebpack: config => { if (isProduction) { config.externals = { 'vue': 'Vue', 'vue-router': 'VueRouter', 'moment': 'moment' } } } chainWebpack: config => { if (isProduction) { config.plugin('html') .tap(args => { args[0].cdn = cdn; return args; }) } } }
到目前为止已经解决了开发模式不使用CDN,生产模式使用CDN的问题和动态在html中注入CDN的问题。
可能你会遇到和我一样的问题
预发布build测试,但无权www.cppcns.com使用生产上的CDN问题,那么我们必须再添加一个环境变量来区分预发布build的模式。(vue-cli 3.0 环境变量文档)这里我添加一个IS_LOCAL_BUILD,首先我们在vue.cofnig.js同路径下创建一个.en.production.local :
// .en.production.local` 内容: IS_LOCAL_BUILD = 'isLocalBuild'
修改vue.config.js如下:
const isProduction = process.env.NODE_ENV === 'production'; const isLocalBuild = process.env.IS_LOEmXeTBCAL_BUILD === 'isLocalBuild'; const JS_CDN = isLocalBuild ? [ 预发布CDN(例如那些免费的CDN) ] : [ 生产环CDN ]; const CSS_CDN = isLocalBuild ? [预发布CDN]: [生产CDN] const cdn = { css: CSS_CDN, js: JS_CDN } module.exports = { configureWebpack: config => { if (isProduction) { config.externals = { 'vue': 'Vue', 'vue-router': 'VueRouter', 'moment': 'moment' } } } chainWebpack: config => { if (isProduction) { config.plugin('html') .tap(args => { args[0].cdn = cdn; return args; }) } } }
ok,上面区分了生产、预发布和开发环境使用CDN的问题,这样就不用根据不同环境手动去修改CDN了。不过又一点要注意:⚠️预发布版本的构建才需要添加.en.production.local。
完整的vue.config.js(供参考)
const path = require('path');
const CompressionWebpackPlugin = require('compression-webpack-plugin');
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
const productionGzipExtensions = ['js', 'css'];
const isProduction = prhttp://www.cppcns.comocess.env.NODE_ENV === 'production';
function resolve(dir) {
return path.join(__dirname, dir);
}
// 预发布环境
const isLocalBuild = process.env.IS_LOCAL_BUILD === 'isLocalBuild';
console.log('前端文件预EmXeTB发布打包- isLocalBuild:', isLocalBuild);
// 非externals CND前缀设置
const CDN_URL = isLocalBuild ? '/' : '//s.zypj.nasetech.com/';
// 区分生产环境打包和预发布打包,使用不同的CDN
const JS_CDN = isLocalBuild ? [
// 预发布CDN
] : [
// 生产CDN
];
const cdn = {
// css: [],
js: JS_CDN
}
module.exports = {
lintOnSave: true,
baseUrl: isProduction ? CDN_URL : '/',
chainWebpack: (config) => {
// build打包才使用CDN
if (isProduction) {
config.plugin('html')
.tap(args => {
args[0].cdn = cdn;
return args;
})
}
config.resolve.alias
.set('assets', resolve('src/assets'))
.set('pages', resolve('src/pages'))
.set('components', resolve('src/components'))
.set('utils', resolve('src/utils'))
},
devServer: {
host: '0.0.0.0',
port: 8080,
https: false,
hotOnly: false,
disableHostCheck: false,
proxy: {
'/api/v0/': {
// 目标 API 地址
target: 'http://127.0.0.1:4545',
// 将主机标头的原点更改为目标URL
changeOrigin: true,
},
},
},
configureWebpack: config => {
// 生产模式
if (isProduction)www.cppcns.com {
config.externals = {
'vue': 'Vue',
'vue-router': 'VueRouter',
'moment': 'moment'
}
// 打包生产.gz包
config.plugins.push(new CompressionWebpackPlugin({
algorithm: 'gzip',
test: new RegExp('\\.(' + productionGzipExtensions.join('|') + ')$'),
threshold: 10240,
minRatio: 0.8
}))
// 添加自定义代码压缩配置
config.plugins.push(
new UglifyJsPlugin({
uglifyOptions: {
compress: {
warnings: false,
drop_debugger: true,
drop_console: true,
},
},
sourceMap: false,
parallel: true,
})
)
}
}
}
* 使用CDN一些有意思的坑:
使用CDN还会遇到一些有意思的事,例如使用beta版的vue导致element UI库有些组件无法正常工作; 使用免费的CDN上线没有多久就GG不能用等悲惨故事!!!
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。
© 著作权归作者所有
发表评论