You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TypeScript包自动生成子路径导出,支持桶导入与组件直接导入

TypeScript包双导入方式配置方案

要实现既支持桶导入又支持组件名子路径导入,同时避免手动维护繁琐配置,按以下步骤操作:

1. 配置桶导入基础

在根目录的src/index.ts中统一导出所有组件,直接支持桶导入:

// src/index.ts
export { TextBox, RadioButton } from './inputs';
export { PrimaryButton, SecondaryButton } from './buttons';

此时其他项目即可通过import { TextBox, PrimaryButton } from 'common-package'导入组件。

2. 自动生成导出配置

手动编写package.json的exports和typeVersions太繁琐,写个Node脚本自动扫描组件并生成配置:

创建generate-exports.js文件:

const fs = require('fs');
const path = require('path');

const srcDir = path.resolve(__dirname, 'src');
const components = [];

// 递归扫描src下的所有组件文件(排除index.ts)
function scanDir(dir) {
  const files = fs.readdirSync(dir);
  for (const file of files) {
    const fullPath = path.join(dir, file);
    const stats = fs.statSync(fullPath);
    if (stats.isDirectory()) scanDir(fullPath);
    else if (file.endsWith('.tsx') && file !== 'index.ts') {
      const componentName = path.basename(file, '.tsx');
      components.push(componentName);
    }
  }
}

scanDir(srcDir);

// 生成exports配置
const exportsConfig = {
  '.': {
    types: './dist/index.d.ts',
    import: './dist/index.js',
    require: './dist/index.cjs'
  }
};

// 为每个组件添加子路径导出规则
components.forEach(name => {
  exportsConfig[`./${name}`] = {
    types: `./dist/${name}.d.ts`,
    import: `./dist/${name}.js`,
    require: `./dist/${name}.cjs`
  };
});

// 生成typeVersions配置
const typeVersionsConfig = {
  '*': components.reduce((acc, name) => {
    acc[`${name}`] = [`dist/${name}.d.ts`];
    return acc;
  }, { '': ['dist/index.d.ts'] })
};

// 更新package.json
const pkgPath = path.resolve(__dirname, 'package.json');
const pkg = require(pkgPath);
pkg.exports = exportsConfig;
pkg.typeVersions = typeVersionsConfig;
fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2));

3. 配置组件单独打包

默认TypeScript编译会保留原目录结构,需要用Rollup将每个组件单独打包到dist根目录:

先安装依赖:

npm install rollup @rollup/plugin-typescript @rollup/plugin-node-resolve @rollup/plugin-commonjs typescript --save-dev

创建rollup.config.js:

import typescript from '@rollup/plugin-typescript';
import { nodeResolve } from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import fs from 'fs';
import path from 'path';

const srcDir = path.resolve(__dirname, 'src');
const components = [];

// 扫描组件文件
function scanDir(dir) {
  const files = fs.readdirSync(dir);
  for (const file of files) {
    const fullPath = path.join(dir, file);
    const stats = fs.statSync(fullPath);
    if (stats.isDirectory()) scanDir(fullPath);
    else if (file.endsWith('.tsx') && file !== 'index.ts') {
      components.push({
        name: path.basename(file, '.tsx'),
        input: fullPath
      });
    }
  }
}

scanDir(srcDir);

// 生成每个组件的打包配置
const componentConfigs = components.map(comp => ({
  input: comp.input,
  output: [
    { file: `dist/${comp.name}.js`, format: 'esm' },
    { file: `dist/${comp.name}.cjs`, format: 'cjs' }
  ],
  plugins: [
    nodeResolve(),
    commonjs(),
    typescript({ declaration: true, declarationDir: 'dist', outDir: 'dist' })
  ]
}));

// 根入口的打包配置
const rootConfig = {
  input: 'src/index.ts',
  output: [
    { file: 'dist/index.js', format: 'esm' },
    { file: 'dist/index.cjs', format: 'cjs' }
  ],
  plugins: [
    nodeResolve(),
    commonjs(),
    typescript({ declaration: true, declarationDir: 'dist', outDir: 'dist' })
  ]
};

export default [...componentConfigs, rootConfig];

4. 串联打包流程

在package.json中添加脚本,自动生成配置并打包:

{
  "scripts": {
    "generate-exports": "node generate-exports.js",
    "build": "npm run generate-exports && rollup -c"
  }
}

5. 测试导入方式

运行npm run build完成打包后,其他项目即可使用两种导入方式:

  • 桶导入:import { TextBox, PrimaryButton } from 'common-package'
  • 子路径导入:import TextBox from 'common-package/TextBox'

后续新增组件时,只需重新执行npm run build,脚本会自动扫描新增组件并更新导出配置。

内容的提问来源于stack exchange,提问作者eVolve

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 04:33:25