angular - Typescript - 在文件中执行代码而不导入它们
问题描述
有什么方法可以在文件中运行代码而不将它们导入 TypeScript(Angular 项目)?也许通过 tsconfig 中的某些配置指定文件模式?
我想做的是将一些类注册到一个全局对象中,但我不想在单个文件中维护类列表。我宁愿在每个类定义下都有一行简单的代码,如下所示:
export class MyClassToRegister {...}
GlobalRegistry.register(MyClassToRegister);
我知道导入文件时会执行此代码,但有时为时已晚。关于如何实现这一点的任何信息?
解决方案
是的,通过使用 Webpack,require.context(...)
您可以将文件目录导入到您的包中。
快速说明:您仍在将文件导入包中,但您不必静态定义每个导入路径,或者在添加/删除文件时手动保持它们是最新的。
文件结构:
让我们使用这个示例文件结构:
src/
items/
item1.ts
item2.ts
item3.ts
registry.ts
index.ts
以下是我们需要从目录中获取的项目:
//item1.ts, item2.ts, item3.ts
import GlobalRegistry from "../registry";
export class Item1 {
//...
}
GlobalRegistry.register(Item1);
加载的项目将使用此服务(或任何您的业务逻辑)注册自己 - 这证明项目正在加载:
//registry.ts
export default class GlobalRegistry {
static _items = [];
static register(cls){
console.log('Register class: ', cls.name);
this._items.push(cls.name);
}
static getItems(){
return this._items;
}
}
需要.context(...)
用于require.context(...)
要求 'items' 目录下的所有文件:
//index.ts
import GlobalRegistry from './registry';
// Import all files under './items/*.ts'
var context = require.context('./items', true, /\.ts$/);
context.keys().forEach((key) => {
context(key);
});
console.log('Loaded classes:', GlobalRegistry.getItems());
最后,为了让 TypeScript 满意,我们声明了require.context()
Webpack 提供的接口:
//references.d.ts
// Extend @types/node NodeRequire type to define Webpack's context function
declare interface NodeRequire {
context: (dir: string, includeSubdirs: boolean, filter: RegExp) => any;
}
// Tell TypeScript that there is a global `require` variable available to us
declare var require: NodeRequire;
结果:
当应用程序运行时,您应该会看到已注销:
Register class: Item1
Register class: Item2
Register class: Item3
Loaded classes: (3) ["Item1", "Item2", "Item3"]
笔记:
1. 包含 的顺序 如果您首先引用单个类,则不保证包含的顺序。
例如,如果您显式导入一个类型并将其用作值,则该类型将在其他仅通过require.context(...)
.
示例 - 使用 Item2 作为值:
//index.ts
/* require.context(...) stuff is here */
import {Item2} from './items/Item2';
let myItem = new Item2(); // use Item2 as a value
更改加载顺序:
Register class: Item2
Register class: Item1
Register class: Item3
Loaded classes: (3) ["Item2", "Item1", "Item3"]
但请注意,仅按类型(而不是按值)引用不会改变加载顺序
let myItem: Item2; // just referencing by type won't affect load order
2.需要函数依赖警告
您可能会在构建过程中收到警告,例如:require function is used in a way in which dependencies cannot be statically extracted
.
这不一定有什么问题,只是 Webpack 让你知道你正在做一些时髦的事情require
——这是真的 :)
执行此动态要求可能会影响捆绑包的摇树或其他静态分析(即,如果不使用这些类型,则不能从捆绑包中排除它们)。但这可能是一个公平的权衡,因为不必手动管理文件导入 - 您必须根据自己的需求/项目目标进行评估。
推荐阅读
- javascript - Action for clicked marker on Google Map
- lodash - Rollupjs:忽略代码行
- tensorflow - Tensorflow 代码准确率没有提高
- css - Ionic 3 如何在自定义离子输入中垂直居中文本?
- javascript - 从匹配文本的位置获取值
- twilio - Twilio 可编程聊天消息数据
- c# - asp.net:如何通过特定行中的复选框更新 GridView 中的数据
- r - 使用 2 种不同颜色的线框绘图
- vba - 公式拖拽查询
- ibm-cloud - 尝试从 IBM Cloud 控制台供应 Analytics Engine 时出错:BXNIM0511E