vue-cli配置CDN

860 阅读1分钟

前言

作为一个苦命的打工仔,领导心血来潮突然觉得vue-cli项目的包内容太大,要求把部分依赖拆出来通过cdn引用,没有反抗的余地,哭哈哈的去弄这玩意

1、在vue-cli中给一些依赖使用CDN加速

看到这里,大家第一反应肯定是想着,这不是很简单嘛,在vue.config.js里面的configureWebpack加上externals,再在/public/index.html 引入对应的cdn链接就直接完事了(代码如下)。嘿嘿,还真就是那么回事,简简单单,那请继续往下看

vue.config.js

module.exports = defineConfig({
  lintOnSave: false,
  publicPath: "./",
  filenameHashing: true,
  outputDir: `dist/${PAGE_NAME}`,
  pages: getPages(),
  
  // 加上externals排除打包依赖
  configureWebpack: {
    externals: {
      'vue': 'Vue',
      'vue-router': 'VueRouter',
      'vuex': 'Vuex',
      'view-ui-plus': 'ViewUIPlus'
    }
})

index.html

单页面&多页面 都一样

<!DOCTYPE html>
<html lang="">
  <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">
    <title><%= htmlWebpackPlugin.options.title %></title>
  </head>
  // CDN链接
  <script src="https://unpkg.com/vue@3.2.13/dist/vue.global.js"></script>
  <script src="https://unpkg.com/vue-router@4.1.6"></script>
  <script src="https://unpkg.com/vuex@4.1.0"></script>
  <script src="https://unpkg.com/view-ui-plus"></script>
  <link rel="stylesheet" href="https://unpkg.com/view-ui-plus/dist/styles/viewuiplus.css" />
  
  <body>
    <noscript>
      <strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
    </noscript>
    <div id="app"></div>
    <!-- built files will be auto injected -->
  </body>

好了,已经写完可以收工了,摸一下鱼,明天跟领导汇报工作进度。

好了,重启服务,进入页面,熟练打开控制台看console,卧槽,怎么控制台有一行vue.global.js的提示

You are running a development build of Vue.
Make sure to use the production build (*.prod.js) when deploying for production.

去vue官网查了一下,发现 unpkg.com/vue@3.2.13/… 这条cdn是只能用于development下的,prod要用 unpkg.com/vue@3.2.13/… 内心os:这 咋整,要我每次打包跟开发手动切换cdn嘛,会被人cute的把

2、html-webpack-plugin 闪亮登场

webpack的externals排除打包依赖的配置不变,通过在html-webpack-plugin这个plugin配置属性,然后在index.html上获取到cdn的数组,遍历数组生成script标签

多页面实现方案

cdn.js

const CDN = {
  // 开发环境下使用 vue.global.js
  development: {
    js: [
      "https://unpkg.com/vue@3.2.13/dist/vue.global.js",
      "https://unpkg.com/vue-router@4.1.6",
      "https://unpkg.com/vuex@4.1.0",
      "https://unpkg.com/view-ui-plus",
    ],
    css: ["https://unpkg.com/view-ui-plus/dist/styles/viewuiplus.css"],
  },
  production: {
    // 打包环境下使用 vue.global.prod.js
    js: [
      "https://unpkg.com/vue@3.2.13/dist/vue.global.prod.js",
      "https://unpkg.com/vue-router@4.1.6",
      "https://unpkg.com/vuex@4.1.0",
      "https://unpkg.com/view-ui-plus",
    ],
    css: ["https://unpkg.com/view-ui-plus/dist/styles/viewuiplus.css"],
  }
};
const env = process.env.NODE_ENV
module.exports = CDN[env]

vue.config.js

// 引入cdn
const cdn = require('../cdn')

module.exports = defineConfig({
  lintOnSave: false,
  publicPath: "./",
  filenameHashing: true,
  outputDir: `dist/${PAGE_NAME}`,
  pages: {
    // 页面入口,这里的属性在通过webpack的打包会之际传递给html-webpack-plugin
    // 在index.html里面遍历 CDN 后批量生成script标签
    client: {
        publicPath: "./",
        entry: "src/modules/client/main.js",
        filename: "index.html",
        title: "client",
        template: "public/index.html",
        outputDir: "dist/client",
        chunks: ["chunk-vendors", "chunk-common", "client"],
        // cdn 列表
        cdn
      }
  }
  configureWebpack: {
    externals: {
      'vue': 'Vue',
      'vue-router': 'VueRouter',
      'vuex': 'Vuex',
      'view-ui-plus': 'ViewUIPlus'
    }
  }
})

index.html

单页面&多页面 都一样

<!DOCTYPE html>
<html lang="">
  <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">
    <title><%= htmlWebpackPlugin.options.title %></title>
  </head>
  <% for (let i in htmlWebpackPlugin.options.cdn.js) { %>
    <script type="text/javascript" src="<%= htmlWebpackPlugin.options.cdn.js[i] %>"></script>
  <% } %>

  <% for (let i in htmlWebpackPlugin.options.cdn.css) { %>
    <link rel="stylesheet" href="<%= htmlWebpackPlugin.options.cdn.css[i] %>" />
  <% } %>

  <body>
    <noscript>
      <strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
    </noscript>
    <div id="app"></div>
    <!-- built files will be auto injected -->
  </body>
</html>

单页面实现

vue.config.js

// 引入cdn
const cdn = require('../cdn')
module.exports = defineConfig({
  lintOnSave: false,
  publicPath: "./",
  outputDir: `dist/${PAGE_NAME}`,
  // pages: getPages(),
  configureWebpack: {
    externals: {
      'vue': 'Vue',
      'vue-router': 'VueRouter',
      'vuex': 'Vuex',
      'view-ui-plus': 'ViewUIPlus'
    }
  },
  // 单页面在这里给html-webpack-plugin 添加 cdn 配置
  chainWebpack: config => {
    config.plugin('html').tap(args => {
      args[0].title = 'title';
      args[0].cdn = cdn
      return args;
    })
  }
})

最后的最后,这样子就可以实现根据不同的打包环境变量来控制引入不同的cdn~~~~~~~~~~~~