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 相关文章推荐
js 发个判断字符串是否为符合标准的函数
Apr 27 Javascript
javascript 全角转换实现代码
Jul 17 Javascript
[原创]js获取数组任意个不重复的随机数组元素
Mar 15 Javascript
Confirmer JQuery确认对话框组件
Jun 09 Javascript
javaScript函数中执行C#代码中的函数方法总结
Aug 07 Javascript
js中Math之random,round,ceil,floor的用法总结
Dec 26 Javascript
jquery获取复选框被选中的值
Mar 22 Javascript
jQuery通过ajax方法获取json数据不执行success的原因及解决方法
Oct 15 Javascript
JSON 必知必会 观后记
Oct 27 Javascript
JavaScript数组排序小程序实现解析
Jan 13 Javascript
JavaScript indexOf()原理及使用方法详解
Jul 09 Javascript
鸿蒙系统中的 JS 开发框架
Sep 18 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
PHPMailer邮件类利用smtp.163.com发送邮件方法
2008/09/11 PHP
深入解析PHP的Yii框架中的event事件机制
2016/03/17 PHP
浅谈php中fopen不能创建中文文件名文件的问题
2017/02/06 PHP
Div Select挡住的解决办法
2008/08/07 Javascript
js将long日期格式转换为标准日期格式实现思路
2013/04/07 Javascript
控制input输入框中提示信息的显示和隐藏的方法
2014/02/12 Javascript
使用jquery中height()方法获取各种高度大全
2014/04/02 Javascript
javascript检查浏览器是否已经启用XX功能
2015/07/10 Javascript
Node.js 应用跑得更快 10 个技巧
2016/04/03 Javascript
JavaScript实现设计模式中的单例模式的一些技巧总结
2016/05/17 Javascript
Js操作DOM元素及获取浏览器高宽的简单方法
2016/09/08 Javascript
微信小程序 UI布局常用技巧整理总结
2016/12/05 Javascript
使用contextMenu插件实现Bootstrap table弹出右键菜单
2017/02/20 Javascript
Javascript中八种遍历方法的执行速度深度对比
2017/04/25 Javascript
vue使用原生js实现滚动页面跟踪导航高亮的示例代码
2018/10/25 Javascript
发布Angular应用至生产环境的方法
2018/12/10 Javascript
javascript实现弹出层效果
2019/12/10 Javascript
微信公众号中的JSSDK接入及invalid signature等常见错误问题分析(全面解析)
2020/04/11 Javascript
解决在Vue中使用axios POST请求变成OPTIONS的问题
2020/08/14 Javascript
[02:53]DOTA2亚洲邀请赛 NewBee战队巡礼
2015/02/03 DOTA
在python中使用xlrd获取合并单元格的方法
2018/12/26 Python
详解Ubuntu16.04安装Python3.7及其pip3并切换为默认版本
2019/02/25 Python
给Python学习者的文件读写指南(含基础与进阶)
2020/01/29 Python
自定义Django Form中choicefield下拉菜单选取数据库内容实例
2020/03/13 Python
Django模板标签中url使用详解(url跳转到指定页面)
2020/03/19 Python
Python面向对象魔法方法和单例模块代码实例
2020/03/25 Python
python 连续不等式语法糖实例
2020/04/15 Python
Python实现JS解密并爬取某音漫客网站
2020/10/23 Python
Python之京东商品秒杀的实现示例
2021/01/06 Python
斐乐美国官方网站:FILA美国
2019/03/01 全球购物
Clarks鞋澳大利亚官方网站:Clarks Australia
2019/12/25 全球购物
关爱女孩行动实施方案
2014/03/13 职场文书
人身意外保险授权委托书
2014/10/01 职场文书
小学教师党员承诺书
2015/04/27 职场文书
Angular性能优化之第三方组件和懒加载技术
2021/05/10 Javascript
Java Optional<Foo>转换成List<Bar>的实例方法
2021/06/20 Java/Android