angular - 在 Angular 应用程序中,TSLint 可以通过路径映射 iso 通过相对路径强制导入模块吗?
问题描述
假设我对 Angular 项目有以下设置:
apps/my-app
libs/my-comp/my-lib
在 my-app 代码中,我使用来自 my-lib 的代码。我可以通过 typescript 导入来导入 my-lib 代码,例如import ../../libs/my-comp/my-lib
,但这很丑陋且容易出错。使用路径映射,我可以模拟模块导入,例如import { MyLibModule} from @my-comp/my-lib
. 干净多了。
但是,我们可以强制执行吗?我们如何防止开发人员使用相对路径从另一个模块导入代码?对此有 TSLint 规则吗?我们应该编写自定义 TSLint 代码吗?有人已经尝试过这样做:)?
解决方案
我们有类似的设置,我们实现了 2 个自定义 lint 规则:
- 禁止从
my-lib
相对进口进口 @my-comp/my-lib
禁止从库本身导入
也许更好的设置是使用nx-workspace(参见 Prebuilt Constraints 部分)。它具有类似的规则并增加了更多:
- Libs 无法导入应用程序。
- 通过 loadChildren 加载库的项目也不能使用 ESM 导入来导入它。
- 不允许循环依赖。
- 无法使用相对导入来导入库。
这是我们禁止从库中相对导入的规则的实现。它有效,但可能存在一些我们尚未发现的严重问题(比如减慢 lint :)
import * as ts from 'typescript';
import * as Lint from 'tslint';
export class Rule extends Lint.Rules.AbstractRule {
static readonly FAILURE_STRING = `Import should be from '${Rule.SHARED_IMPORT}'`;
static readonly SHARED_IMPORT = 'my-lib';
public apply(sourceFile: ts.SourceFile): Lint.RuleFailure[] {
return this.applyWithFunction(sourceFile, walk);
}
}
function walk(ctx: Lint.WalkContext<void>) {
return ts.forEachChild(ctx.sourceFile, cb);
function cb(node: ts.Node): void {
if (node.kind !== ts.SyntaxKind.ImportDeclaration) {
return;
}
const importLocation = getImportLocation(node.getText());
if (containsIncorrectImportFromSharedFolder(importLocation)) {
const locationWidth = importLocation.length + 3;
const fix = new Lint.Replacement(node.getEnd() - locationWidth, locationWidth, `'${Rule.SHARED_IMPORT}';`);
return ctx.addFailureAtNode(node, Rule.FAILURE_STRING, fix);
}
return ts.forEachChild(node, cb);
}
function containsIncorrectImportFromSharedFolder(importLocation: String): boolean {
return importLocation.indexOf(Rule.SHARED_IMPORT) > -1 && importLocation !== Rule.SHARED_IMPORT;
}
function getImportLocation(location: string): string {
const importLocation = location.match(/'(.*?[^'])'/);
return importLocation !== null ? importLocation[1] : '';
}
}
您必须将规则编译为js
with tsc
:
node "node_modules/typescript/bin/tsc" tools/tslint-rules/myLibImportRule.ts
你必须将它添加到tslint.json
:
"rulesDirectory": [
...
"tools/tslint-rules",
...
],
"rules": {
...,
"my-lib-import": true,
...
}
规则名称是文件的名称myLibImportRule.js
=> my-lib-import
。
推荐阅读
- javascript - 连接天气 api 时出现数据错误
- python - 如何为 f(x) 方程编写代码以在 python 中给出其对应的 f(-x)?
- discord.py - 如何让不和谐机器人响应 webhook。Python。不和谐.py
- python - Selenium 正在为肯定有文本的元素返回空文本
- python - 在 lex 聊天机器人中渲染 html
- php - 具有固定标记的 PHP 正则表达式 html 数据属性
- php - 如何在 laravel join 中解码
- python - 通过命令提示符从 C# 运行 python 脚本
- c++ - GSM MQTT+CMT(短信阅读)
- python - 使用 SciPy 引导 SWAP 时设置条件的问题