Skip to content

dynamicLoadFile

动态加载远程CSS/JS / 插入内联Style

引入版本

0.50.0

Demo

ts
import { dynamicLoadFile } from '@wyfex/iutils'

/**
 * 1. 最简用法:仅加载 CSS
 */
// 默认 options.suffix=css,挂载 document.head
const cssDom = await dynamicLoadFile(
  'https://cdn.jsdelivr.net/npm/normalize.css/normalize.css'
)
console.log('css加载完成DOM', cssDom)
// 卸载当前样式
cssDom.unload()

/**
 * 2. CSS + 自定义 id + 自定义挂载容器
 */
const customHeadBox = document.createElement('div')
document.head.append(customHeadBox)

const elPlusCss = await dynamicLoadFile(
  'https://cdn.jsdelivr.net/npm/element-plus/dist/index.css',
  {
    id: 'el-plus-main-css',
    container: customHeadBox
  }
)
elPlusCss.unload()

/**
 * 3. 加载 JS + async 异步脚本
 */
const vueScript = await dynamicLoadFile(
  'https://cdn.jsdelivr.net/npm/vue@3/dist/vue.global.prod.js',
  {
    suffix: 'js',
    id: 'vue3-global',
    async: true
  }
)
vueScript.unload()

/**
 * 4. 加载 JS + defer 延迟执行
 */
const echartsJs = await dynamicLoadFile(
  'https://cdn.jsdelivr.net/npm/echarts/dist/echarts.min.js',
  {
    suffix: 'js',
    id: 'echarts-core',
    defer: true
  }
)
echartsJs.unload()

/**
 * 5. JS 完整配置:async + defer + 自定义容器 + id
 */
const scriptWrap = document.getElementById('script-wrapper') as HTMLElement

const axiosJs = await dynamicLoadFile(
  'https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js',
  {
    suffix: 'js',
    id: 'axios-cdn',
    async: true,
    defer: true, // async /defer 同时存在时浏览器优先遵循 async 规则
    container: scriptWrap
  }
)
axiosJs.unload()

/**
 * 6. 内联 style 样式文本 + id + 自定义容器
 */
const styleSlot = document.createElement('div')
document.head.appendChild(styleSlot)

const globalStyle = await dynamicLoadFile(
  `
    .app-wrap { width: 1400px; margin: 0 auto; }
    .text-primary { color: #409eff; }
  `,
  {
    suffix: 'style',
    id: 'global-app-style',
    container: styleSlot
  }
)
globalStyle.unload()

/**
 * 7. 缓存去重演示(相同资源不会重复创建 DOM)
 */
// 第一次加载
const domA = await dynamicLoadFile('https://test/demo.css', {
  id: 'demo-cache'
})
// 重复调用,直接读取缓存
const domB = await dynamicLoadFile('https://test/demo.css', {
  id: 'demo-cache'
})
console.log(domA === domB) // true

/**
 * 8. 捕获资源加载失败(404 / 网络错误)
 */
try {
  await dynamicLoadFile('https://xxx/not-found.js', {
    suffix: 'js',
    id: 'error-demo',
    defer: true
  })
} catch (err) {
  console.error('资源加载异常', err)
  // 内部自动执行 unload,清理缓存与DOM
}

/**
 * 9. 一次性清空所有动态加载资源
 */
// 批量加载
await dynamicLoadFile('https://cdn/reset.css', { id: 'reset-style' })
await dynamicLoadFile('https://cdn/common.js', {
  suffix: 'js',
  id: 'common-sdk'
})

// 全局销毁全部 link / script / style
dynamicLoadFile.clearAll()

/**
 * 10. Options 全字段同时传入(完整配置全覆盖)
 */
const resourceBox = document.querySelector(
  '#custom-resource-container'
) as HTMLElement

const lodashScript = await dynamicLoadFile(
  'https://cdn.jsdelivr.net/npm/lodash/lodash.min.js',
  {
    suffix: 'js',
    id: 'lodash-cdn',
    async: false,
    defer: true,
    container: resourceBox
  }
)
lodashScript.unload()

基于 MIT 许可发布