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 22 Javascript
精心挑选的15个jQuery下拉菜单制作教程
Jun 15 Javascript
jquery formValidator插件ajax验证 内容不做任何修改再离开提示错误的bug解决方法
Jan 04 Javascript
使用Javascript简单实现图片无缝滚动
Dec 05 Javascript
js中DOM三级列表(代码分享)
Mar 20 Javascript
通过学习bootstrop导航条学会修改bootstrop颜色基调
Jun 11 Javascript
js+html5实现复制文字按钮
Jul 15 Javascript
ES6学习教程之对象字面量详解
Oct 09 Javascript
详解如何用VUE写一个多用模态框组件模版
Sep 27 Javascript
微信小程序实现弹出层效果
May 26 Javascript
d3绘制基本的柱形图的实现代码
Dec 12 Javascript
Layui实现数据表格默认全部显示(不要分页)
Oct 26 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
要会喝咖啡也要会知道咖啡豆
2021/03/03 咖啡文化
建立动态的WML站点(三)
2006/10/09 PHP
用PHP和ACCESS写聊天室(十)
2006/10/09 PHP
php xml留言板 xml存储数据的简单例子
2009/08/24 PHP
探讨Smarty中如何获取数组的长度以及smarty调用php函数的详解
2013/06/20 PHP
preg_match_all使用心得分享
2014/01/31 PHP
WordPress中用于检索模版的相关PHP函数使用解析
2015/12/15 PHP
Docker搭建自己的PHP开发环境
2018/02/24 PHP
js类中的公有变量和私有变量
2008/07/24 Javascript
7款吸引人眼球的jQuery/CSS3特效实例分享
2013/04/25 Javascript
解决用jquery load加载页面到div时,不执行页面js的问题
2014/02/22 Javascript
JavaScript中伪协议 javascript:使用探讨
2014/07/18 Javascript
浅谈JavaScript中指针和地址
2015/07/26 Javascript
jquery简单插件制作(fn.extend)完整实例
2016/05/24 Javascript
js学习阶段总结(必看篇)
2016/06/16 Javascript
详解nodejs实现本地上传图片并预览功能(express4.0+)
2017/06/28 NodeJs
NodeJs搭建本地服务器之使用手机访问的实例讲解
2018/05/12 NodeJs
微信小程序中上传图片并进行压缩的实现代码
2018/08/28 Javascript
详解Vue.js在页面加载时执行某个方法
2018/11/20 Javascript
详解React项目中碰到的IE问题
2019/03/14 Javascript
vue路由权限校验功能的实现代码
2020/06/07 Javascript
Python 常用的安装Module方式汇总
2017/05/06 Python
Python3.4编程实现简单抓取爬虫功能示例
2017/09/14 Python
python中返回矩阵的行列方法
2018/04/04 Python
django从请求到响应的过程深入讲解
2018/08/01 Python
Pandas中resample方法详解
2019/07/02 Python
python 解决tqdm模块不能单行显示的问题
2020/02/19 Python
基于Tensorflow一维卷积用法详解
2020/05/22 Python
使用OpenCV实现道路车辆计数的使用方法
2020/07/15 Python
运动鞋中的劳斯莱斯:索康尼(SAUCONY)
2017/08/09 全球购物
美国领先的家庭智能音响系统品牌:Sonos
2018/07/20 全球购物
Pureology官网:为染色头发打造最好的产品
2019/09/13 全球购物
中医专业应届生求职信
2013/11/17 职场文书
大学生职业生涯规划范文
2014/01/22 职场文书
批评与自我批评材料
2014/02/15 职场文书
2014年便民服务中心工作总结
2014/12/20 职场文书