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

如何强制TypeScript模块内容在运行时执行?

问题描述

我有多个仅包含TypeScript类的模块,每个类都带有类装饰器,作用是把类信息添加到一个Map中。这些类从来不会通过名称直接实例化,而是由应用的其他部分通过访问这个Map获取类信息来创建对象。

现在的问题是:因为这些模块里的内容从未被显式引用,运行时模块不会被评估,导致类装饰器没被执行,Map里也没任何内容。

我试过两种临时解决办法,但都属于hack手段:

  • 在其他模块里对每个模块的某个类执行无意义的new操作(只要一个就能强制模块评估);
  • 在每个TS模块里加一个空函数,初始化时从其他模块调用这个函数。

想知道有没有其他方法,可以强制那些未被应用其他部分显式引用的模块在运行时被评估?仅导入模块无法实现这个效果。

解决方案

1. 动态导入模块

在应用初始化的入口文件中,批量动态导入目标模块,无需引用任何导出内容,仅触发导入操作即可强制模块评估:

// 入口文件
async function init() {
  // 列出所有需要加载的类模块路径
  const modulePaths = [
    './classA.ts',
    './classB.ts',
    './classC.ts'
  ];
  // 并行导入所有模块
  await Promise.all(modulePaths.map(path => import(path)));
  // 此时装饰器已执行,Map中已包含类信息
}

init();

如果是Node.js环境,也可以直接用require加载:

// Node.js环境
const modulePaths = [
  './classA',
  './classB'
];
modulePaths.forEach(path => require(path));

2. 配置构建工具保留副作用模块

如果使用Webpack、Vite这类构建工具,默认的tree-shaking会剔除未被引用的模块。可以通过配置标记这些模块为有副作用(装饰器执行属于副作用),避免被剔除:

  • Webpack:在webpack.config.js中对目标模块设置sideEffects: true:
const path = require('path');

module.exports = {
  module: {
    rules: [
      {
        test: /\.ts$/,
        include: path.resolve(__dirname, './classes'), // 类模块所在目录
        sideEffects: true
      }
    ]
  }
};

之后在入口文件中静态导入模块即可:

import './classA.ts';
import './classB.ts';
  • Vite:在package.json中添加sideEffects字段指定目标模块:
{
  "sideEffects": [
    "./src/classes/*.ts"
  ]
}

同样在入口文件静态导入模块,Vite会保留并评估这些模块。

3. 创建模块索引统一导入

在类模块所在目录创建index.ts,统一导出所有模块:

// ./classes/index.ts
export * from './classA.ts';
export * from './classB.ts';
export * from './classC.ts';

然后在入口文件导入该索引模块(无需使用导出内容):

import './classes/index.ts';

结合构建工具的sideEffects配置,索引模块会被评估,进而触发所有子模块的装饰器执行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 14:01:17