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 相关文章推荐
简单实用的反馈表单无刷新提交带验证
Nov 15 Javascript
jquery改变disabled的boolean状态的三种方法
Dec 13 Javascript
JavaScript中的ArrayBuffer详细介绍
Dec 08 Javascript
innerHTML中标签可以换行的方法汇总
Aug 14 Javascript
JavaScript常用基础知识强化学习
Dec 09 Javascript
动态设置form表单的action属性的值的简单方法
May 25 Javascript
jQuery数据检索中根据关键字快速定位GridView指定行的实现方法
Jun 08 Javascript
利用vue-router实现二级菜单内容转换
Nov 30 Javascript
微信小程序 网络请求(post请求,get请求)
Jan 17 Javascript
解决URL地址中的中文乱码问题的办法
Feb 10 Javascript
浅谈在Vue-cli里基于axios封装复用请求
Nov 06 Javascript
详解在微信小程序的JS脚本中使用Promise来优化函数处理
Mar 06 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
深入了解php4(2)--重访过去
2006/10/09 PHP
php 获取百度的热词数据的代码
2012/02/18 PHP
解析mysql left( right ) join使用on与where筛选的差异
2013/06/18 PHP
php给一组指定关键词添加span标签的方法
2015/03/31 PHP
HR vs ForZe BO3 第一场 2.13
2021/03/10 DOTA
textContent在Firefox下与innerText等效的属性
2007/05/12 Javascript
网站被黑的假象--ARP欺骗之页面中加入一段js
2007/05/16 Javascript
javascript 表单的友好用户体现
2009/01/07 Javascript
使用jQuery简化Ajax开发 Ajax开发入门
2009/10/14 Javascript
jQuery获取样式中的背景颜色属性值/颜色值
2012/12/17 Javascript
javascript+xml实现简单图片轮换(只支持IE)
2012/12/23 Javascript
如何让页面加载完成后执行js
2013/06/26 Javascript
jqueryUI里拖拽排序示例分析
2015/02/26 Javascript
简介BootStrap model弹出框的使用
2016/04/27 Javascript
JS定义类的六种方式详解
2016/05/12 Javascript
JavaScript中的splice方法用法详解
2016/07/20 Javascript
js本地图片预览实现代码
2016/10/09 Javascript
jquery对所有input type=text的控件赋值实现方法
2016/12/02 Javascript
原生js实现密码输入框值的显示隐藏
2017/07/17 Javascript
微信小程序授权登录及解密unionId出错的方法
2018/09/26 Javascript
原生js实现照片墙效果
2020/10/13 Javascript
jQuery实现推拉门效果
2020/10/19 jQuery
[07:09]2014DOTA2国际邀请赛-Newbee再次发威成功晋级决赛
2014/07/19 DOTA
Python的lambda匿名函数的简单介绍
2013/04/25 Python
用TensorFlow实现lasso回归和岭回归算法的示例
2018/05/02 Python
基于python的图片修复程序(实现水印去除)
2018/06/04 Python
python实现飞机大战
2018/09/11 Python
python 绘制拟合曲线并加指定点标识的实现
2019/07/10 Python
简单介绍django提供的加密算法
2019/12/18 Python
Python根据字典的值查询出对应的键的方法
2020/09/30 Python
ASP.NET Core中的配置详解
2021/02/05 Python
matplotlib bar()实现多组数据并列柱状图通用简便创建方法
2021/02/24 Python
美国在线宠物用品商店:Entirely Pets
2017/01/01 全球购物
关于食品安全的演讲稿范文(三篇)
2019/10/21 职场文书
台式电脑蓝牙适配器怎么安装?台式电脑蓝牙适配器安装教程
2022/04/08 数码科技
centos7安装mysql5.7经验记录
2022/05/02 Servers