
Product
Introducing Socket Fix for Safe, Automated Dependency Upgrades
Automatically fix and test dependency updates with socket fix—a new CLI tool that turns CVE alerts into safe, automated upgrades.
vite-plugin-cdn-import-async
Advanced tools
Import packages asynchronously from CDN for the vite plugin
This plugin is forked from vite-plugin-cdn-import and allows you to specify modules that should be loaded in defer/async mode in addition.
npm:
npm install vite-plugin-cdn-import-async --save-dev
yarn:
yarn add vite-plugin-cdn-import-async -D
Specify async
or defer
to mode
param whthin configs of the module you want to import asynchronously from CDN:
// vite.config.js
import cdnImport from 'vite-plugin-cdn-import-async'
export default {
plugins: [
cdnImport({
modules: [
{
name: 'react',
var: 'React',
mode: 'async', // 'async' atrribute will be added to its <script> tag.
path: `https://cdn.jsdelivr.net/npm/react@18.2.0/umd/react.production.min.js`,
},
{
name: 'lottie-web',
var: 'lottie',
mode: 'defer', // 'defer' atrribute will be added to its <script> tag.
path: `https://cdn.jsdelivr.net/npm/lottie-web@5.10.0/build/player/lottie.min.js`,
},
{
name: 'axios', // Module without 'mode' param will be loaded synchronously.
var: 'axios',
path: 'https://cdn.jsdelivr.net/npm/axios@1.2.1/dist/axios.min.js',
}
],
}),
],
}
This demo will generate codes below into the output file:
<script>function __cdnImportAsyncHandler(o,n){n&&window.cdnImportAsync_loadingErrorModules.push(o);var d=new CustomEvent("asyncmoduleloaded",{detail:{module:o,isError:!!n}});window.dispatchEvent(d)}window.cdnImportAsync_loadingErrorModules=window.cdnImportAsync_loadingErrorModules||[];</script>
<script async onload="__cdnImportAsyncHandler('React')" onerror="__cdnImportAsyncHandler('React', true)" src="https://cdn.jsdelivr.net/npm/react@18.2.0/umd/react.production.min.js"></script>
<script defer onload="__cdnImportAsyncHandler('lottie')" onerror="__cdnImportAsyncHandler('lottie', true)" src="https://cdn.jsdelivr.net/npm/lottie-web@5.10.0/build/player/lottie.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/axios@1.2.1/dist/axios.min.js"></script>
By default, every module that defined in plugin config will generate its <script>
tag into the output file, no matter this module was used in the project or not.
But now you can set attribute data-cdn-import
in <meta>
tag of the input file, to determind which module should generate <script>
into the output file.
For example (example/react/index.html
):
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" data-cdn-import="React,lottie" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Example</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>
According to data-cdn-import="React,lottie"
, plugin will only handle React
and lottie
modules and generate their <script>
into the output file (example/react/dist/index.html
):
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Example</title>
<script>window.__cdnImportAsync_varToNameMap={"React":"react","lottie":"lottie-web"};</script>
<script>function __cdnImportAsyncHandler(o,n){n&&window.cdnImportAsync_loadingErrorModules.push(o);var d=new CustomEvent("asyncmoduleloaded",{detail:{module:o,isError:!!n}});window.dispatchEvent(d)}window.cdnImportAsync_loadingErrorModules=window.cdnImportAsync_loadingErrorModules||[];</script>
<script async onload="__cdnImportAsyncHandler('React')" onerror="__cdnImportAsyncHandler('React', true)" src="https://cdn.jsdelivr.net/npm/react@18.2.0/umd/react.production.min.js"></script>
<script defer onload="__cdnImportAsyncHandler('lottie')" onerror="__cdnImportAsyncHandler('lottie', true)" src="https://cdn.jsdelivr.net/npm/lottie-web@5.10.0/build/player/lottie.min.js"></script>
<script type="module" crossorigin src="/assets/index.c9473e27.js"></script>
<link rel="stylesheet" href="/assets/index.cd9c0392.css">
</head>
<body>
<div id="root"></div>
</body>
</html>
Using suffix @async
or @defer
within data-cdn-import
can also generate asynchronous <script>
tag of marked module.
Example
Notice that here's no mode: 'async'
in the configs of React module:
// vite.config.js
import cdnImport from 'vite-plugin-cdn-import-async'
export default {
plugins: [
cdnImport({
modules: [
{
name: 'react',
var: 'React',
path: `https://cdn.jsdelivr.net/npm/react@18.2.0/umd/react.production.min.js`,
},
{
name: 'lottie-web',
var: 'lottie',
mode: 'defer',
path: `https://cdn.jsdelivr.net/npm/lottie-web@5.10.0/build/player/lottie.min.js`,
},
{
name: 'axios',
var: 'axios',
path: 'https://cdn.jsdelivr.net/npm/axios@1.2.1/dist/axios.min.js',
}
],
}),
],
}
And the input file (example/react/index.html
) likes:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" data-cdn-import="React@async,lottie" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Example</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>
According to React@async
within data-cdn-import
, the React module will generate <script>
tag with async
attribute into the output file (example/react/dist/index.html
):
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Example</title>
<script>window.__cdnImportAsync_nameToVar={"react":"React","lottie-web":"lottie"};</script>
<script>function __cdnImportAsyncHandler(o,n){n&&window.cdnImportAsync_loadingErrorModules.push(o);var d=new CustomEvent("asyncmoduleloaded",{detail:{module:o,isError:!!n}});window.dispatchEvent(d)}window.cdnImportAsync_loadingErrorModules=window.cdnImportAsync_loadingErrorModules||[];</script>
<script async onload="__cdnImportAsyncHandler('React')" onerror="__cdnImportAsyncHandler('React', true)" src="https://cdn.jsdelivr.net/npm/react@18.2.0/umd/react.production.min.js"></script>
<script defer onload="__cdnImportAsyncHandler('lottie')" onerror="__cdnImportAsyncHandler('lottie', true)" src="https://cdn.jsdelivr.net/npm/lottie-web@5.10.0/build/player/lottie.min.js"></script>
<script type="module" crossorigin src="/assets/index.c9473e27.js"></script>
<link rel="stylesheet" href="/assets/index.cd9c0392.css">
</head>
<body>
<div id="root"></div>
</body>
</html>
In addition to async
or defer
as the value of mode
, here's other avalable values for lazy-loading:
Value of mode | Description |
---|---|
DOMContentLoaded | Module will start being loaded within DOMContentLoaded event of window . |
load | Module will start being loaded within load event of window . |
[milliseconds] | Module will start being loaded in specified milliseconds after load event emits. |
Example
In vite.config.js
:
export default defineConfig({
plugins: [
importToCDN({
modules: [
{
name: 'react',
var: 'React',
mode: 'DOMContentLoaded',
path: `https://cdn.jsdelivr.net/npm/react@18.2.0/umd/react.production.min.js`,
},
{
name: 'lottie-web',
var: 'lottie',
mode: '3000',
path: `https://cdn.jsdelivr.net/npm/lottie-web@5.10.0/build/player/lottie.min.js`,
},
{
name: 'axios',
var: 'axios',
mode: 'load',
path: 'https://cdn.jsdelivr.net/npm/axios@1.2.1/dist/axios.min.js',
}
],
}),
reactRefresh(),
],
})
Or the entry file:
<meta data-cdn-import="React@DOMContentLoaded,lottie@3000,axios@load" />
The output file would be like:
<script>window.__cdnImportAsync_nameToVar={"react":"React","lottie-web":"lottie"};</script>
<script>function __cdnImportAsyncHandler(o,n){n&&window.cdnImportAsync_loadingErrorModules.push(o);var d=new CustomEvent("asyncmoduleloaded",{detail:{module:o,isError:!!n}});window.dispatchEvent(d)}window.cdnImportAsync_loadingErrorModules=window.cdnImportAsync_loadingErrorModules||[];</script>
<script>function __cdnImportAsync_deferredLoader(n,r){var c=document.createElement("script");c.onload=function(){__cdnImportAsyncHandler(n)},c.onerror=function(){__cdnImportAsyncHandler(n,!0)},c.src=r,document.body.appendChild(c)}</script>
<script>!function(){window.addEventListener("DOMContentLoaded",function e(){__cdnImportAsync_deferredLoader("React","https://cdn.jsdelivr.net/npm/react@18.2.0/umd/react.production.min.js"),window.removeEventListener("DOMContentLoaded",e)},!1)}();</script>
<script>!function(){window.addEventListener("load",function e(){setTimeout(function(){__cdnImportAsync_deferredLoader("lottie","https://cdn.jsdelivr.net/npm/lottie-web@5.10.0/build/player/lottie.min.js")},3000),window.removeEventListener("load",e)},!1)}();</script>
<script>!function(){window.addEventListener("load",function e(){__cdnImportAsync_deferredLoader("axios","https://cdn.jsdelivr.net/npm/axios@1.2.1/dist/axios.min.js"),window.removeEventListener("load",e)},!1)}();</script>
Once a module is loaded asynchronously by mode
config, you should create an function to handle it while using it in pages:
export function cdnAsyncImport(moduleName: string, isDev: boolean): Promise<any> {
if (isDev) {
return Promise.reject()
}
return new Promise((resolve, rejects) => {
const errorModules = window.cdnImportAsync_loadingErrorModules || []
const moduleVar = window.__cdnImportAsync_nameToVar[moduleName]
if (errorModules.includes(moduleVar)) {
rejects()
} else if (window[moduleVar]) {
resolve(window[moduleVar])
} else {
window.addEventListener(
'asyncmoduleloaded',
(e: any) => {
const { detail } = e || {}
if (detail && !detail.isError && window[moduleVar]) {
resolve(window[moduleVar])
} else {
rejects()
}
},
false
)
}
})
}
cdnAsyncImport('lottie-web', import.meta.env.DEV).then(lottie => {
// Async module has been successfully loaded.
console.log(lottie)
}).catch(() => {
// Handling DEV or Error case
import('lottie-web').then(...)
})
Other basic ussages see vite-plugin-cdn-import.
FAQs
Import packages asynchronously from CDN for the vite plugin
The npm package vite-plugin-cdn-import-async receives a total of 127 weekly downloads. As such, vite-plugin-cdn-import-async popularity was classified as not popular.
We found that vite-plugin-cdn-import-async demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Product
Automatically fix and test dependency updates with socket fix—a new CLI tool that turns CVE alerts into safe, automated upgrades.
Security News
CISA denies CVE funding issues amid backlash over a new CVE foundation formed by board members, raising concerns about transparency and program governance.
Product
We’re excited to announce a powerful new capability in Socket: historical data and enhanced analytics.