npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@ldesign/dynamic-import

v0.0.5

Published

一个功能强大的Node.js动态包管理工具,支持运行时动态导入npm包、自动依赖安装、批量导入、版本控制等功能

Readme

🚀 Dynamic Import Manager

一个功能强大的Node.js动态包管理工具,让你在运行时轻松导入npm包!

npm version TypeScript License: MIT Test Coverage

✨ 特性亮点

🎯 动态加载 - 运行时动态导入任意npm包,无需预先安装⚡ 自动安装 - 智能检测并自动安装缺失的依赖包 🔄 批量导入 - 支持同时导入多个包,提升效率 📦 版本控制 - 精确控制包版本,避免版本冲突 🎨 导出灵活 - 支持default、named、namespace多种导出方式🛡️ 类型安全 - 完整的TypeScript支持,开发更安心🚀 高性能 - 智能缓存机制,避免重复导入 🔧 易配置 - 支持多种包管理器(默认pnpm)🗂️ 临时安装 - 支持临时安装,自动清理package.json ⚙️ 灵活依赖 - 支持安装到devDependencies或dependencies

📦 安装

# 使用 npm
npm install @ldesign/dynamic-import

# 使用 yarn
yarn add @ldesign/dynamic-import

# 使用 pnpm (推荐)
pnpm add @ldesign/dynamic-import

🎯 快速开始

基础用法

import { dynamicImport } from '@ldesign/dynamic-import'

// 动态导入lodash包(默认临时安装到devDependencies)
const { module: lodash } = await dynamicImport('lodash')
console.log(lodash.chunk([1, 2, 3, 4], 2)) // [[1, 2], [3, 4]]

// 指定版本导入,安装到dependencies
const { module: axios } = await dynamicImport('axios', {
  version: '1.6.0',
  exportType: 'default',
  isTemporary: false, // 保留在package.json中
  installType: 'prod', // 安装到dependencies
})
const response = await axios.get('https://api.github.com')

// 临时安装(不保留在package.json中)
const { module: chalk } = await dynamicImport('chalk', {
  isTemporary: true, // 默认值,安装后自动清理
  installType: 'dev', // 默认值,安装到devDependencies
})
console.log(chalk.blue('Hello World!'))

高级用法

import { DynamicPackageManager } from '@ldesign/dynamic-import'

// 创建管理器实例
const manager = await DynamicPackageManager.create()

// 批量导入多个包
const result = await manager.importBatch({
  packages: [
    { packageName: 'lodash', exportType: 'default' },
    { packageName: 'dayjs', version: '1.11.0' },
    {
      packageName: 'chalk',
      exportType: 'named',
      namedExports: ['red', 'blue'],
    },
  ],
  parallel: true,
  maxConcurrency: 3,
})

console.log(`成功导入 ${result.successful.length} 个包`)
console.log(`失败 ${result.failed.length} 个包`)

📚 API 文档

便捷函数

dynamicImport(packageName, options?)

动态导入单个包的便捷函数。

const result = await dynamicImport('package-name', {
  version: '1.0.0', // 指定版本
  exportType: 'default', // 导出类型: 'default' | 'named' | 'namespace'
  namedExports: ['func1'], // 具名导出列表(exportType为'named'时使用)
  forceReinstall: false, // 是否强制重新安装
  isTemporary: true, // 是否临时安装(默认true,安装后从package.json删除)
  installType: 'dev', // 安装类型: 'dev' | 'prod'(默认'dev')
})

importFromSpec(packageSpec, exportType?)

从包规范字符串导入包。

// 基础用法
const result = await importFromSpec('[email protected]')

// 作用域包
const result = await importFromSpec('@types/[email protected]', 'namespace')

batchImport(packages, options?)

批量导入多个包。

const result = await batchImport(
  [
    { packageName: 'lodash', exportType: 'default' },
    { packageName: 'axios', version: '1.6.0' },
  ],
  {
    parallel: true, // 是否并行导入
    maxConcurrency: 3, // 最大并发数
    continueOnError: true, // 出错时是否继续
  }
)

核心类

DynamicPackageManager

主要的包管理器类,提供完整的动态导入功能。

// 创建实例
const manager = await DynamicPackageManager.create()
const manager = new DynamicPackageManager('pnpm', '/custom/path')

// 导入包
const result = await manager.import({
  packageName: 'package-name',
  version: '1.0.0',
  exportType: 'default'
})

// 批量导入
const batchResult = await manager.importBatch({
  packages: [...],
  parallel: true
})

// 包管理
await manager.installPackage('package-name', '1.0.0')
await manager.uninstallPackage('package-name')

// 缓存管理
manager.clearAllCaches()
const cacheInfo = manager.getCacheInfo()

🎨 使用示例

示例1:动态加载工具库

import { dynamicImport } from '@ldesign/dynamic-import'

async function processData(data: any[]) {
  // 动态加载lodash进行数据处理
  const { module: _ } = await dynamicImport('lodash')

  return _(data)
    .filter(item => item.active)
    .groupBy('category')
    .mapValues(group => group.length)
    .value()
}

示例2:条件导入不同的包

import { dynamicImport } from '@ldesign/dynamic-import'

async function createLogger(type: 'simple' | 'advanced') {
  if (type === 'simple') {
    const { module: chalk } = await dynamicImport('chalk', {
      exportType: 'named',
      namedExports: ['red', 'green', 'blue'],
    })
    return {
      info: (msg: string) => console.log(chalk.blue(msg)),
      error: (msg: string) => console.log(chalk.red(msg)),
    }
  } else {
    const { module: winston } = await dynamicImport('winston')
    return winston.createLogger({
      level: 'info',
      format: winston.format.json(),
      transports: [new winston.transports.Console()],
    })
  }
}

示例3:插件系统

import { DynamicPackageManager } from '@ldesign/dynamic-import'

class PluginSystem {
  private manager = await DynamicPackageManager.create()
  private plugins = new Map()

  async loadPlugin(pluginName: string, version?: string) {
    try {
      const result = await this.manager.import({
        packageName: pluginName,
        version,
        exportType: 'default',
      })

      this.plugins.set(pluginName, result.module)
      console.log(`✅ 插件 ${pluginName} 加载成功`)

      return result.module
    } catch (error) {
      console.error(`❌ 插件 ${pluginName} 加载失败:`, error.message)
      throw error
    }
  }

  async loadPlugins(pluginConfigs: Array<{ name: string; version?: string }>) {
    const packages = pluginConfigs.map(config => ({
      packageName: config.name,
      version: config.version,
      exportType: 'default' as const,
    }))

    const result = await this.manager.importBatch({
      packages,
      parallel: true,
      continueOnError: true,
    })

    result.successful.forEach(plugin => {
      this.plugins.set(plugin.packageName, plugin.module)
    })

    return {
      loaded: result.successful.length,
      failed: result.failed.length,
      plugins: this.plugins,
    }
  }
}

⚙️ 配置选项

DynamicImportOptions

interface DynamicImportOptions {
  packageName: string // 包名
  version?: string // 指定版本
  exportType?: ExportType // 导出类型
  namedExports?: string[] // 具名导出列表
  forceReinstall?: boolean // 强制重新安装
  installDir?: string // 自定义安装目录
  packageManager?: PackageManager // 包管理器类型
}

BatchImportOptions

interface BatchImportOptions {
  packages: DynamicImportOptions[] // 包配置列表
  parallel?: boolean // 是否并行安装
  maxConcurrency?: number // 最大并发数
  continueOnError?: boolean // 失败时是否继续
}

导出类型

  • 'default' - 默认导出(推荐)
  • 'named' - 具名导出,需要指定 namedExports
  • 'namespace' - 命名空间导出,导入整个模块

包管理器支持

  • 'pnpm' - 高性能的npm替代品(默认和推荐)
  • 'yarn' - Yarn Package Manager
  • 'npm' - Node Package Manager

🔧 高级用法

自定义包管理器

import { DynamicPackageManager } from '@ldesign/dynamic-import'

// 使用特定的包管理器和目录
const manager = new DynamicPackageManager('yarn', '/custom/project/path')

// 或者自动检测(默认优先使用pnpm)
const autoManager = await DynamicPackageManager.create('/custom/path')

缓存管理

// 获取缓存信息
const cacheInfo = manager.getCacheInfo()
console.log(`缓存大小: ${cacheInfo.size}`)
console.log(`缓存的包: ${cacheInfo.packages.join(', ')}`)

// 清除特定包的缓存
manager.clearCache('package-name')

// 清除所有缓存
manager.clearAllCaches()

// 预加载包(不导入)
await manager.preloadPackages([
  { name: 'lodash', version: '4.17.21' },
  { name: 'axios', version: '1.6.0' },
])

错误处理

import {
  DynamicImportError,
  PackageInstallError,
  ModuleImportError,
} from '@ldesign/dynamic-import'

try {
  const result = await dynamicImport('non-existent-package')
} catch (error) {
  if (error instanceof PackageInstallError) {
    console.error('包安装失败:', error.message)
    console.error('包名:', error.packageName)
    console.error('退出码:', error.exitCode)
  } else if (error instanceof ModuleImportError) {
    console.error('模块导入失败:', error.message)
    console.error('包名:', error.packageName)
  } else if (error instanceof DynamicImportError) {
    console.error('动态导入错误:', error.message)
  }
}

版本控制

// 精确版本
await dynamicImport('lodash', { version: '4.17.21' })

// 版本范围(使用semver)
await dynamicImport('lodash', { version: '^4.17.0' })
await dynamicImport('lodash', { version: '~4.17.20' })

// 最新版本(默认)
await dynamicImport('lodash')

// 强制重新安装特定版本
await dynamicImport('lodash', {
  version: '4.17.21',
  forceReinstall: true,
})

💡 最佳实践

1. 错误处理

始终使用try-catch包装动态导入操作:

async function safeImport(packageName: string) {
  try {
    return await dynamicImport(packageName)
  } catch (error) {
    console.error(`导入 ${packageName} 失败:`, error.message)
    return null
  }
}

2. 性能优化

利用缓存机制避免重复导入:

const manager = await DynamicPackageManager.create()

// 第一次导入会安装和缓存
const lodash1 = await manager.import({ packageName: 'lodash' })

// 第二次导入直接使用缓存,速度更快
const lodash2 = await manager.import({ packageName: 'lodash' })

3. 批量操作

对于多个包的导入,使用批量操作提升效率:

// ✅ 推荐:批量导入
const result = await batchImport(
  [
    { packageName: 'lodash' },
    { packageName: 'axios' },
    { packageName: 'dayjs' },
  ],
  { parallel: true }
)

// ❌ 不推荐:逐个导入
const lodash = await dynamicImport('lodash')
const axios = await dynamicImport('axios')
const dayjs = await dynamicImport('dayjs')

4. 类型安全

充分利用TypeScript类型定义:

import type { DynamicImportResult } from '@ldesign/dynamic-import'

// 指定返回类型
const result: DynamicImportResult<typeof import('lodash')> =
  await dynamicImport('lodash')

// 使用泛型
const { module } = await dynamicImport<typeof import('axios')>('axios')

❓ 常见问题

Q: 支持哪些Node.js版本?

A: 支持Node.js 16.0.0及以上版本。

Q: 可以在浏览器中使用吗?

A: 不可以,这是一个专为Node.js环境设计的工具,依赖于文件系统和包管理器。

Q: 如何处理包的依赖冲突?

A: 工具会使用指定的包管理器来解决依赖冲突。建议使用pnpm以获得更好的依赖管理。

Q: 导入的包会被永久安装吗?

A: 是的,包会被安装到项目的node_modules目录中。如需清理,可以手动删除或使用包管理器的清理命令。

Q: 支持私有npm仓库吗?

A: 支持,工具会使用当前环境配置的npm registry设置。

Q: 如何调试导入失败的问题?

A: 可以通过捕获错误对象来获取详细的错误信息,包括包名、错误类型和原始错误。

🤝 贡献指南

我们欢迎所有形式的贡献!

开发环境设置

# 克隆仓库
git clone https://github.com/your-username/dynamic-import-manager.git
cd dynamic-import-manager

# 安装依赖
pnpm install

# 运行测试
pnpm test

# 构建项目
pnpm build

# 检查代码质量
pnpm lint

提交规范

  • 🐛 fix: 修复bug
  • feat: 新功能
  • 📝 docs: 文档更新
  • 🎨 style: 代码格式化
  • ♻️ refactor: 代码重构
  • perf: 性能优化
  • test: 测试相关

📄 许可证

本项目采用 MIT 许可证

🙏 致谢

感谢所有为这个项目做出贡献的开发者!


如果这个项目对你有帮助,请给它一个 ⭐️!

报告问题 · 功能请求 · 贡献代码