vue项目优化之 cdn引入依赖,减少打包体积。

webpack 对Externals的说明

外部扩展(Externals)

externals 配置选项提供了「从输出的 bundle 中排除依赖」的方法。相反,所创建的 bundle 依赖于那些存在于用户环境(consumer's environment)中的依赖。此功能通常对 library 开发人员来说是最有用的,然而也会有各种各样的应用程序用到它。

externals

string [string] object function RegExp

防止将某些 import 的包(package)打包到 bundle 中,而是在运行时(runtime)再去从外部获取这些扩展依赖(external dependencies)

例如,从 CDN 引入 jQuery,而不是把它打包:

index.html


webpack.config.js

module.exports = {
  //...
  externals: {
    jquery: 'jQuery',
  },
};

这样就剥离了那些不需要改动的依赖模块,换句话,下面展示的代码还可以正常运行:

import $ from 'jquery';

$('.my-element').animate(/* ... */);

具有外部依赖(external dependency)的 bundle 可以在各种模块上下文(module context)中使用,例如 CommonJS, AMD, 全局变量和 ES2015 模块。外部 library 可能是以下任何一种形式:

  • root:可以通过一个全局变量访问 library(例如,通过 script 标签)。
  • commonjs:可以将 library 作为一个 CommonJS 模块访问。
  • commonjs2:和上面的类似,但导出的是 module.exports.default.
  • amd:类似于 commonjs,但使用 AMD 模块系统

好了说了那么多,总结来说就是

将不怎么需要更新的第三方库脱离webpack打包,不被打入bundle中,从而减少打包时间,但又不影响运用第三方库的方式,例如import方式等

在vue项目里面 vue.config怎么去配置呢?

每次都手动去在index.html里面手动引入外部依赖的cdn路径的。肯定不是我们需要的,这太笨了。

需要解决的问题:

a. 不打包指定的外部依赖
b. 在index.html自动引入外部依赖

怎么运用externals:
例如:
在index.html中引入CDN的资源react全家桶之类的资源



webpack.config.js配置如下:

  module.exports = {
     ...
     output: {
       ...
     },
     externals : {
        xlsx: 'XLSX', 
        lodash: {
            commonjs: 'lodash',
            amd: 'lodash',
            root: '_', // 指向全局变量
        },
        redux:'redux',
      // 暂时注释,此库采用cdn引入,会导致报错,cdn引入方式,是暴露了X6全局变量,Graph等属性是挂载在X6全局变量里面,
      // 但是里面挂载的对象属性都不一样。暂未找到解决方案
      // '@antv/x6': 'X6',  
       'jquery':'jQuery'  // 由于@antv/x6依赖了jQuery,这里配置忽略,采用cdn方式引入
     }
   }

这样的话在应用程序中依旧可以以import的方式(还支持其他方式)引用:

import XLSX from 'xlsx'
import { createStore, combineReducers, applyMiddleware } from 'redux';

XLSX就是暴露的全局变量,xlsx库的名称,例如: import XLSX from 'xlsx'

这样不仅之前对第三方库的用法方式不变,还把第三方库剥离出webpack的打包中,从而加速webpack的打包速度。

完整的externals配置如下,我已经将externals对象单独导出一个文件

image.png

可以看到上面还有个cdn对象,这个对象是干嘛用的,下面我们就来介绍一下。上面我们已经介绍了配置externals 来忽略打包了。但是我们不可能真的就每次都去手动引入cdn链接,这样就太蠢了。
此时我们肯定是希望运行打包命令的时候自动加载到模板里面。此时我们就需要借助一个webpack的插件 html-webpack-plugin

html-webpack-plugin的使用

html-webpack-plugin是webpack的一个插件,可以动态的创建和编辑html内容,在html中使用esj语法可以读取到配置中的参数,简化了html文件的构建。(ejs知识点请自行百度,类似jsp跟asp的模板语法

最基础的使用方式

new HtmlWebpackPlugin({
   // 其他默认配置
  cdn: externalConfig// cdn配置
})

定义好了配置则可以再模板里面使用ejs模板语法来读取这个变量了。模板语法可以if、for等函数

index.html



  
    
    
    
    
    <%= htmlWebpackPlugin.options.title %>
    
    <% if(htmlWebpackPlugin.options.cdn){ htmlWebpackPlugin.options.cdn.css.forEach(function(item){%>
      
    <% }) }%>
  
  
    
    
<% if(htmlWebpackPlugin.options.cdn){ htmlWebpackPlugin.options.cdn.js.forEach(function(item){%> <% }) }%>

可以看到我先判断有没有cdn这个变量,然后再循环遍历输出。这样就实现了编译之后自动引入cdn外部依赖了。

在vue项目中。我们在vue.config中的 chainWebpack里面,其实我们不需要再去引入html-webpack-plugin这个库了。因为已经集成了的

chainWebpack: config => {
      config.plugin('html').tap((args) => {
        args[0].title = 'edge-compute-platform'

        // 配置cdn
        if (isProduction) {
            args[0].cdn = externalsConfig.cdn
        }
        return args
    })
}

看vue-cli源码就知道config.plugin('html')就是html-webpack-plugin如果只是简单定义一个变量而已就是上面这样的用法。所以到这里引入cdn就完成了。

你可能感兴趣的:(vue项目优化之 cdn引入依赖,减少打包体积。)