preface

If you just want to quickly configure a CDN, you can go directly to the Quick Configuration section.

Chrome will soon default to a policy that restricts the distribution of sub-resources on private networks. This will prevent non-HTTPS protocols from using third-party links, which will prevent development environments from using CDN. This strategy didn’t work with CSS stylesheets when I tested it. After this security policy is enabled, you may encounter this error in the future: I’m currently Chrome 91, and I can find this policy by typing Chrome ://flags/#block-insecure-private-network-requests in the Chrome address bar. It will be enabled by default in future releases. If you now actively enable this policy, then the development environment using CDN you will get an error: The request client is not a secure context and The resource is in more-private address space \local ‘. The blog was changed very much on 2021-07-08. Originally, Vue was also released 3, and the CDN introduction method of Vue3 has not been discussed in this module.

Select the CDN of the Vue

The imported vUE file must be the browser version, the minimum required == runtime source ==, depending on your vUE version, the selected file may vary:

  • Vue2 users can select vue.runtime.min.js.
  • Vue3 version of the user to select: vue. Runtime. Global. Prod. Js.

What is the difference between the runtime source code and the full version? The runtime source code lacks a compiler, whereas the full version does, because vue-loader already compiles the template, so it doesn’t need to compile again. This means that the runtime source code is smaller, as shown in the official vue2 or VUe3 documentation.

I used bootcDN’s runtime compression module, which is smaller. Remember to use the same CDN as the version of the dependent package in your package.json to avoid version bugs.

How to introduce CDN?

Because the development environment cannot safely use third-party external chains, third-party CDNS can only be used in production environments.

The import method is to register the CDN template variable in vue.config.js and insert it in public/index.html. One hand ready, one hand inserted.

One hand insert

For projects built using vue-CLI, you can insert the prepared CDN template == in the head element of the project /public/index.html ==.

My code is as follows:

<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>vue-app</title>

  <! Insert CDN position, write the following line -->
  <%= htmlWebpackPlugin.options.cdns %>
</head>
Copy the code

This uses the template parameters of the HTML-webpack-plugin, which you can use to prepare parameters to insert into the template.

As you can see, we insert the < % = htmlWebpackPlugin. Options. CDNS % > parameter, this is what we need to prepare the CDN template.

Syntax such as <%= %> is an EJS template syntax and can be read in its Chinese documentation for more details.

In preparing

Go to the project /vue.config.js file and create it if it doesn’t exist.

Preparation consists of two steps:

  • Set external dependencies: Ignore modules already introduced with THE CDN when packaging.

  • Add template parameters: CDN resource elements ready for insertion.

In the following code, moment. js and Vue3 are introduced using CDN and ignored when packaging:

/ * *@file vue.config.js */

module.exports = {
  chainWebpack: (config) = > {
    // Only use CDN in production environment
    if (process.env.NODE_ENV === "production") {
      // Ignore the vue and moment modules
      config.externals({
        vue: "Vue".moment: "moment"});// Modify HtmlWebpackPlugin parameters, implant CDNS template parameters, value Vue3 and moment.js CDN link
      config.plugin("html").tap((args) = > {
        args[0].cdns = ` < script SRC = "https://cdn.bootcdn.net/ajax/libs/vue/3.1.2/vue.runtime.global.prod.min.js" Crossorigin = "anonymous" > < / script > < script SRC = "https://cdn.bootcdn.net/ajax/libs/moment.js/2.29.1/moment.min.js" crossorigin="anonymous"> `;
        returnargs; }); }}};Copy the code

Among them:

  • Config. externals config.externals is used to configure external extensions, which do not package external extensions, i.e., build modules. Its key name and value make sense:

    • Key name: The key name of the module that uses an external extension. For example, import VueLib123 from “vue”, module from “vue” is the same, module name is this key name.

    • Value: The value is the global reference to the module after using the CDN. For example, after Vue is introduced using CDN, it is accessed globally using Vue variable, then the value of external extension is Vue.

  • Config.plugin (” HTML “).tap Is used to modify the parameters of HtmlWebpackPlugin. So in public/index. In the HTML you can use the < % = htmlWebpackPlugin. Options. CDNS % > to access the parameters.

  • The Webpack configuration used in the above code is a chain call, and because it involves modifying plug-in parameters, a simple configuration is not possible.
  • I set the Crossorigin attribute in the script element to disable user credential passing, see CORS Settings Attributes.
  • If you want to use third-party CDNS more securely, then SRI is recommended.

Summary + package test

Note: The source code only changed the “project /public/index.html” file and configured vue.config.js, no other changes to the code. This approach does not use THE CDN in the development environment, for the reasons mentioned above in Section 1.

The package.json dependencies of the test code are:

{
  "dependencies": {
    "core-js": "^ 3.6.5." "."moment": "^ 2.29.1"."vue": "^ 3.0.0"}}Copy the code

Moment and Vue use CDN introduction.

Package without CDN (to test by commenting out the code added by vue.config.js) :

warning

webpack performance recommendations:
You can limitthe size of your bundles by using import() or require.ensure to lazy load some parts of your application. For more info Visit https://webpack.js.org/guides/code-splitting/ for the File Size Gzipped dist, js, the chunk - vendors. 50 f67bb1. 379.14 KiB js 110.63 KiB dist\js\app.d4b48aed.js 6.54kib 2.45 KiB Images and other types of assets omitted. DONE Build complete. The dist directory is ready to be deployed. INFO Check out deployment instructions at https://cli.vuejs.org/guide/deployment.html Donein5.03 s.Copy the code

App. Vue introduces moment.js to App.

Chunk-vendors are 379.14 KB, and contain three modules, core-JS, Moment, and Vue.

Packaging using CDN:

 DONE  Compiled successfully in720ms 2:52:47 File Size Gzipped dist\js\chunk-vendors.20dbb2c7.js 24.82kib 9.06 KiB dist\js\app.08fbc8da.js 2.02kib 0.99 KiB Images and other types of assets omitted. DONE Build complete. The dist Directory is ready to be deployed. INFO  Check out deployment instructions at https://cli.vuejs.org/guide/deployment.html Donein3.49 s.Copy the code

At this point chunk-Venders are down to 24KB, leaving only core-JS dependencies.

Summary:

This packaging is just an illustration of the basic implementation, but if you find it a bit of a hassle, check out the quick configuration section at the end.

If you want to continue to optimize packaging, it is recommended to learn about asynchronous routing, asynchronous loading, etc., and use require.context with caution.

Quick Configuration

I don’t have time to look up configuration every time, so I just wrapped a function.

  • First, inpublic/index.htmlheadElement to insert the CDN.
<%= htmlWebpackPlugin.options.cdns %>
Copy the code
  • Then create a new fileuseCDNs.jsAt any position, I put itRoot/webpack useCDNs. JsIn the. After creating a new copy of the following code paste in, comments do not want to delete.
/ * *@file useCDNs.js */

/ * *@typedef {string} ModuleName ModuleName */
/ * *@typedef {string} The ModuleRefer module is referenced globally */
/ * *@typedef {string} ElementTem element template */
/ * *@typedef {{mod:ModuleName; refer:ModuleRefer; el:ElementTem}} CDNItem CDN project */

/** * CDN use function. * * This function can specify some modules as external dependencies in the specified development environment and insert the prepared third-party CDN template into the 'public/index.html' file with the parameter 'CDNS' through the HtmlWebpackPlugin. * you can be in ` public/index. The HTML ` use ejs syntax < % = htmlWebpackPlugin. Options. CDNS % > ready to insert the CDN. * *@param {import('webpack-chain')} Config webpack-chain instance *@param {CDNItem[]} CDNS passes in the CDN array * to be used@param {string} Env In which environment to use CDN, default production environment */
module.exports = function useCDNs(config, cdns = [], env = "production") {
  if(process.env.NODE_ENV ! == env)return;

  config.externals(
    cdns.reduce((prev, v) = > {
      prev[v.mod] = v.refer;
      returnprev; }, {})); config.plugin("html").tap((args) = > {
    args[0].cdns = cdns.map((v) = > v.el).join("");
    return args;
  });
};
Copy the code
  • Finally, invue.config.jsIs called as follows:
/ * *@file vue.config.js */

const useCDNs = require("./webpack/useCDNs");

module.exports = {
  chainWebpack: (config) = > {
    useCDNs(config, [
      {
        mod: "vue".refer: "Vue".el: ` < script SRC = "https://cdn.bootcdn.net/ajax/libs/vue/3.1.2/vue.runtime.global.prod.min.js" > < / script > `}, {mod: "moment".refer: "moment".el: ` < script SRC = "https://cdn.bootcdn.net/ajax/libs/moment.js/2.29.1/moment.min.js" crossorigin = "anonymous" > < / script > `,}]); }};Copy the code

Where, mod and refer correspond to the module name and reference name of the external extension, and EL is the CDN element.

For details on the use of useCDNs refer to the original file, which is full of comments.

FAQ

Do you need to delete the import Vue statement?

== Do not delete, can not delete. = =

Because the method in this paper only configures the build environment to use CDN, the development environment still uses the local package in node_moduels, and GG will be deleted if the development environment is deleted.

Where can I find CDN?

I used to use booTCDN, but this house collapsed around the Chinese New Year the year before last, and then did not use it.

You can use UNPKG, which is directly associated with the NPM library.

Or JSDELIVR, the old CDN is guaranteed and supports SRI.

compatibility

Vue-cli3 and VUe-CLI4 are compatible with this configuration mode.

How do stylesheets use third-party CDNS?

First, stylesheets have no external extensions; Second, the limiting sub-resource policy mentioned in the introduction of this article has no effect on CSS.

If you want your CSS to use CDN, you can do so directly in the head element of the public/index.html file, both in development and production.

Suffice it to say, because stylesheets don’t have external extensions. If you were to introduce JS in the same way as above, you would need to remove the CSS introduction from the project, otherwise there would be two stylesheets in production.

For example, if you use ElementUI, in your project you introduce the import “element-ui/lib/theme-chalk/index.css”. If you introduce it again in public/index.html, Or add it again in vue.config.js, causing a secondary import. Although repeated introductions have no effect on the rendering results, doing so can cause the browser to do additional style calculations, costing performance.