欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2022-11-09 19:53:40
前言:上一篇记录文中提到了cdn优化,之前是直接在html中手动注入js,也没有对开发和生产模式进行区分,因为是使用收费的cdn,所以在开发模式会遇到无权使用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不能用等悲惨故事!!!

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