vue-cli3.0如何使用CDN区分开发、生产、预发布环境


Posted in Javascript onNovember 22, 2018

前言:上一篇记录文vue-cli 3.0 build包太大导致首屏过长的解决方案中提到了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不能用等悲惨故事!!!

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
在JQuery dialog里的服务器控件 事件失效问题
Dec 08 Javascript
JS创建类和对象的两种不同方式
Aug 08 Javascript
使用不同的方法结合/合并两个JS数组
Sep 18 Javascript
Js类的静态方法与实例方法区分及jQuery拓展的两种方法
Jun 03 Javascript
JAVA Web实时消息后台服务器推送技术---GoEasy
Nov 04 Javascript
JS实现的几个常用算法
Nov 12 Javascript
Vue.js学习笔记之常用模板语法详解
Jul 25 Javascript
SVG实现时钟效果
Jul 17 Javascript
微信小程序实现topBar底部选择栏效果
Jul 20 Javascript
移动端手指操控左右滑动的菜单
Sep 08 Javascript
jquery实现两个div中的元素相互拖动的方法分析
Apr 05 jQuery
vue实现员工信息录入功能
Jun 11 Javascript
详解三种方式解决vue中v-html元素中标签样式
Nov 22 #Javascript
详解Vue组件之作用域插槽
Nov 22 #Javascript
详解vue中localStorage的使用方法
Nov 22 #Javascript
微信小程序功能之全屏滚动效果的实现代码
Nov 22 #Javascript
layer弹出子iframe层父子页面传值的实现方法
Nov 22 #Javascript
js操作table中tr的顺序实现上移下移一行的效果
Nov 22 #Javascript
从源码里了解vue中的nextTick的使用
Nov 22 #Javascript
You might like
PHP实现网上点歌(二)
2006/10/09 PHP
PHP购物车类Cart.class.php定义与用法示例
2016/07/20 PHP
PHP实现网页内容html标签补全和过滤的方法小结【2种方法】
2017/04/27 PHP
JS完整获取IE浏览器信息包括类型、版本、语言等等
2014/05/22 Javascript
javascript实现炫酷的拖动分页
2015/05/11 Javascript
JavaScript String 对象常用方法总结
2016/04/28 Javascript
iframe中使用jquery进行查找的方法【案例分析】
2016/06/17 Javascript
详解js中的apply与call的用法
2016/07/30 Javascript
关于javascript事件响应的基础语法总结(必看篇)
2016/12/26 Javascript
vue实现动态数据绑定
2017/04/28 Javascript
Vue项目中引入外部文件的方法(css、js、less)
2017/07/24 Javascript
vue编译打包本地查看index文件的方法
2018/02/23 Javascript
基于jQuery实现的设置文本区域的光标位置
2018/06/15 jQuery
原生JS实现列表子元素顺序反转的方法分析
2018/07/02 Javascript
Vue在页面数据渲染完成之后的调用方法
2018/09/11 Javascript
vue中各种通信传值方式总结
2019/02/14 Javascript
uni-app 组件里面获取元素宽高的实现
2019/12/27 Javascript
如何通过JS实现转码与解码
2020/02/21 Javascript
在js文件中引入(调用)另一个js文件的三种方法
2020/09/11 Javascript
JavaScript 防抖和节流遇见的奇怪问题及解决
2020/11/20 Javascript
Python项目 基于Scapy实现SYN泛洪攻击的方法
2019/07/23 Python
Python学习笔记之Django创建第一个数据库模型的方法
2019/08/07 Python
Pycharm调试程序技巧小结
2020/08/08 Python
python实现经纬度采样的示例代码
2020/12/10 Python
使用CSS3的::selection改变选中文本颜色的方法
2015/09/29 HTML / CSS
GNC健安喜官方海外旗舰店:美国著名保健品牌
2017/01/04 全球购物
现代家居用品及礼品:LBC Modern
2018/06/24 全球购物
商务英语应届生自我鉴定
2013/12/08 职场文书
医务人员自我评价
2014/01/26 职场文书
班级活动策划书
2014/02/06 职场文书
同学会主持词
2014/03/18 职场文书
入党积极分子评语
2014/05/04 职场文书
纪律教育学习月活动总结
2014/08/27 职场文书
2014党员干部四风问题对照检查材料思想汇报
2014/09/24 职场文书
详解Vue的options
2021/05/15 Vue.js
WINDOWS 64位 下安装配置mysql8.0.25最详细的教程
2022/03/22 MySQL