vite使用CDN引入第三方库

2022年6月20日 ... ☕️ 3 min read

vite的打包部分,完全交给了rollup。所以打包这部分的配置,在官方文档介绍的并不多,一行带过,而且是库模式的

当这个库要进行发布构建时,请使用 build.lib 配置项,以确保将那些你不想打包进库的依赖进行外部化处理,例如 vue 或 react

如果是以页面应用模式发布的时候,如何配置才能以第三方库的方式(如CDN)引入呢?

既然全部交给了rollup,那么配置自然是在build -> rollupOptions

初步设想是只在打包的时候把需要外部化(external)的第三方库拿出去,在开发模式,依然是用npm安装的模块方式来运行。

// https://vitejs.dev/config/
export default defineConfig(({ command, mode }) => {

  return {
    build: {
      rollupOptions: {
        external: ["@antv/g2plot", "@antv/l7plot"],
        output: {
          globals: {
            "@antv/g2plot": "G2Plot",
            "@antv/l7plot": "L7Plot",
          },
          paths: {
            "@antv/g2plot":
              "https://unpkg.com/@antv/g2plot@latest/dist/g2plot.min.js",
            "@antv/l7plot":
              "https://unpkg.com/@antv/l7plot@latest/dist/umd/l7plot.min.js",
          },
        }
      }
    }
  }
};

如果使用的是iife或者umd模式的文件,上面的配置就够用了。但是很多库只有cjs(commonjs)格式的输出,这个时候如果直接配置,就会 报错,例如

The requested module 'https://unpkg.com/@antv/g2plot@2.4.5/dist/g2plot.min.js' does not provide an export named 'Area'

需要的插件:rollup-plugin-external-globals

import externalGlobals from "rollup-plugin-external-globals";

// https://vitejs.dev/config/
export default defineConfig(({ command, mode }) => {

  return {
    build: {
      rollupOptions: {
        plugins: [
          externalGlobals({
            "@antv/g2plot": "G2Plot",
            "@antv/l7plot": "L7Plot",
          }),
        ],
      }
    }
  }
};

这个插件会为引入的第三方库创建一个全局变量,并把代码转码:

import jq from "jquery";
console.log(jq(".test"));

// into
console.log($(".test"));

关于iife、amd、cmd、cjs、umd、esm

iife全称Immediately Invoked Function Expression,即立即执行函数,我们在做闭包题目中肯定会遇到的那种函数。

(function(){
  // ... stuff
})();

commonjs又叫cjs,是nodejs即服务端广泛使用的模块化机制。简而言之,必须通过module.exports导出变量或者接口,通过require()来导入变量或接口。

// rollup生成的AMD格式文件
define(['exports'], function (exports) {
  const foo = '123';
  function someFunc() {
    // ...stuff
  }
  exports.someFunc = someFunc;
  Object.defineProperty(exports, '__esModule', {value: true});
});

AMD全称Asynchronous Module Definition,它诞生于cjs,但是支持异步模块加载。它使用RequireJS等模块,在浏览器端进行模块加载。CMD就不说了,过渡产品,本身特性被RequireJS支持而退出历史舞台。

UMD全程是Universal Module Definition,兼容iife、amd和iife的写法。

(function (global, factory) {
	typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
	typeof define === 'function' && define.amd ? define(factory) :
	(global.NAME = factory());
}(this, (function () {
    //code
    return obj;
})));

ESM最近使用vite出镜率特别高的词,是ES2015以来的官方标准。我们在TypeScript常用的import / export方法,就是这种。

const increase = (val, total) => total + val;
// ... stuff

export { increase };

浏览器端不能执行,但是较新的浏览器(chrome 61+,firefox 60+,safari 11+),如果把scripttype设置为module,即可识别 import / export

#vite

SideEffect is a blog for front-end web development.
Code by Axiu / rss