我正在使用CustomTransformer从以下位置更新导入:
import { global_spacer_form_element } from '@patternfly/react-tokens';
export const disabledLabelClassNameEx = global_spacer_form_element.var;至
import global_spacer_form_element from '@patternfly/react-tokens/dist/js/global_spacer_form_element';
export const disabledLabelClassNameEx = global_spacer_form_element.var;但是,当使用ts-loader时,我得到了以下输出(直接从ts-loader):
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.disabledLabelClassNameEx = void 0;
const global_spacer_form_element_1 = __importDefault(require("@patternfly/react-tokens/dist/js/global_spacer_form_element"));
exports.disabledLabelClassNameEx = react_tokens_1.global_spacer_form_element.var;
//# sourceMappingURL=Recipient2.js.map它使用的是react_tokens_1.global_spacer_form_element,而不是直接使用global_spacer_form_element。
我认为typescript编译器用来构建react_tokens_1变量的转换器中缺少一些东西。
转换器在其访问器中执行以下操作(为了显示它所采用的路径,我简化了转换器代码,完整代码可以查看here):
const visitor: ts.Visitor = (node) => {
if (ts.isSourceFile(node)) {
return ts.visitEachChild(node, visitor, context)
}
if (!ts.isImportDeclaration(node) /* or if the lib name is not '@patternfly/react-tokens' */) {
return node
}
// for simplicity assume we take all NamedImports and the only found is...
const elements = ['global_spacer_form_element']
const importPath = '@patternfly/react-tokens/dist/js/global_spacer_form_element'
return elements.map((e) => {
return ts.factory.createImportDeclaration(
undefined,
undefined,
ts.factory.createImportClause(
false,
ts.factory.createIdentifier(e),
undefined,
),
ts.factory.createStringLiteral(importPath),
)
})
}我的tsconfig.json
{
"compilerOptions": {
"module": "commonjs",
"target": "es6",
"allowJs": true,
"checkJs": false,
"jsx": "react",
"outDir": "./build",
"removeComments": true,
"pretty": true,
"skipLibCheck": true,
"strict": true,
"moduleResolution": "node",
"esModuleInterop": true,
"noImplicitAny": false,
"sourceMap": true,
"resolveJsonModule" : true
},
"include": [
"./src/**/*"
],
"exclude": [
"./node_modules/*",
"**/*.js"
]
}最后是ts-loader配置:
{
test: /src\/.*\.tsx?$/,
loader: 'ts-loader',
exclude: /(node_modules)/i,
options: {
getCustomTransformers: () => ({
before: [
tsImportPluginFactory({
libraryName: '@patternfly/react-tokens',
libraryDirectory: 'dist/js',
camel2DashComponentName: false
})
]
})
}你知道我还需要更新什么,或者我可以检查什么,以确保这个转换器按照我的预期工作吗?
编辑:对旧的导入的引用消失了,但我之前没有注意到新的导入也被转换了:例如从foobar到foobar_1。
发布于 2021-02-12 04:18:01
TypeScript编译器有四个主要阶段--解析、绑定、类型检查和发出。绑定是标识符之间的关系被解析的地方,但转换发生在“发出”阶段。所以,当你转换的时候已经太晚了,编译器已经弄清楚了它要转换的标识符。
一种方法是遍历文件中的所有节点,找到与导入中的一个节点匹配的标识符,然后通过在该节点的访问器中返回context.factory.createIdentifier(node.escapedText)来重新创建这些标识符。这将使编译器在发出时保留节点的原样。
不过,问题可能是找出文件中的哪些标识符引用了命名的导入标识符。通常,我不建议在转换中使用类型检查器,因为当文件上发生多个转换时,类型检查器可能会导致意外的结果,但是您可以先检查标识符的escapeText是否匹配,然后检查typeChecker.getSymbolAtLocation(node)?.declarations[0]是否等于原始导入声明中找到的命名导出标识符。或者,我认为您必须实现自己的作用域分析。
https://stackoverflow.com/questions/66161672
复制相似问题