Generate a bundle using the jsDelivr CDN to host the external dependencies.
npm i -D unplugin-jsdelivr
Vite
// vite.config.ts
import jsDelivr from "unplugin-jsdelivr/vite";
export default defineConfig({
plugins: [
jsDelivr({
/* options */
}),
],
});
Rollup
// rollup.config.js
import jsDelivr from "unplugin-jsdelivr/rollup";
export default {
plugins: [
jsDelivr({
modules: [{ module: "lodash" }],
// See below for more options
}),
// other plugins
],
};
Webpack
// webpack.config.js
module.exports = {
/* ... */
plugins: [
require("unplugin-jsdelivr/webpack")({
modules: [{ module: "lodash" }],
// See below for more options
}),
],
};
Vue CLI
// vue.config.js
module.exports = {
configureWebpack: {
plugins: [
require("unplugin-jsDelivr/webpack")({
modules: [{ module: "lodash" }],
// See below for more options
}),
],
},
};
esbuild
// esbuild.config.js
import { build } from "esbuild";
build({
/* ... */
plugins: [
require("unplugin-jsDelivr/esbuild")({
modules: [{ module: "lodash" }],
// See below for more options
}),
],
});
{
// Required
modules: [...] // See Modules
// Optional
cwd: process.cwd();
endpoint: "npm" // or "gh"
enforce: undefined // "pre" | "post" - only applicable to Vite and Webpack
}
// Options
{
modules: [{ module: "lodash" }];
// Changes
import { map, merge as LodashMerge } from "lodash";
// to
import {
map,
merge as LodashMerge,
} from "https://cdn.jsdelivr.net/npm/lodash@4.17.21/+esm";
}
{
modules: [
{
module: "lodash",
transform: (moduleName, importName) => `${moduleName}/${importName}`,
},
];
// Changes
import { map, merge as LodashMerge } from "lodash";
// to
import map from "https://cdn.jsdelivr.net/npm/lodash@4.17.21/map/+esm";
import LodashMerge from "https://cdn.jsdelivr.net/npm/lodash@4.17.21/merge/+esm";
}
The plugin aims to resolve all the external modules into resolvable CDN URLs.
If only lodash
is included with no transform function passed through, it only resolves the package to the ESM bundle online. The version is resolved from your package.json
.
import { map, merge as LodashMerge } from "lodash";
import {
map,
merge as LodashMerge,
} from "https://cdn.jsdelivr.net/npm/lodash@4.17.21/+esm";
Alternatively, if a transform function is passed through to the config, it will first transform the member style imports into default imports before resolving to the ESM bundles online.
transform: (moduleName, importName) => `${moduleName}/${importName}`
`moduleName` -> `lodash`
`importName` -> `map` and `merge`
import map from "lodash/map";
import LodashMerge from "lodash/merge";
Reference: babel-plugin-transform-imports
This creates more efficient development bundles as we're not loading the whole library. It also helps identify the exact files needed to be loaded from the CDN, producing the following code:
import map from "https://cdn.jsdelivr.net/npm/lodash@4.17.21/map/+esm";
import LodashMerge from "https://cdn.jsdelivr.net/npm/lodash@4.17.21/merge/+esm";
TODO With the list of modules, we can use the jsDelivr Combine API to generate a CDN based vendor bundle of all external dependencies. Currently blocked until ESM support is added to Combine API