vue-cli3.0如何使用CDN区分开发、生产、预发布环境
前言:上一篇记录文中提到了cdn优化,之前是直接在html中手动注入js,也没有对开发和生产模式进行区分,因为是使用收费的cdn,所以在开发模式会遇到无权使用cdn的问题。要是使用cdn写死在html中,不同环境需要手动的切换cdn,那么早晚有一天会搞乱,下面就说说怎么在vue-cli 3.0 中根据不同环境动态注入cdn。
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测试,但无权使用生产上的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_local_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 = process.env.node_env === 'production'; function resolve(dir) { return path.join(__dirname, dir); } // 预发布环境 const islocalbuild = process.env.is_local_build === 'islocalbuild'; console.log('前端文件预发布打包- 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) { 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不能用等悲惨故事!!!
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
上一篇: 什么是产后忧郁症
下一篇: 忧郁症测试:你离忧郁症有多远