首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在自定义转换器之后,typescript仍然使用对旧导入的引用

在自定义转换器之后,typescript仍然使用对旧导入的引用
EN

Stack Overflow用户
提问于 2021-02-12 03:39:02
回答 1查看 201关注 0票数 1

我正在使用CustomTransformer从以下位置更新导入:

代码语言:javascript
复制
import { global_spacer_form_element } from '@patternfly/react-tokens';
export const disabledLabelClassNameEx = global_spacer_form_element.var;

代码语言:javascript
复制
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):

代码语言:javascript
复制
"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):

代码语言:javascript
复制
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

代码语言:javascript
复制
{
  "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配置:

代码语言:javascript
复制
{
  test: /src\/.*\.tsx?$/,
  loader: 'ts-loader',
  exclude: /(node_modules)/i,
  options: {
        getCustomTransformers: () => ({
            before: [
                tsImportPluginFactory({
                    libraryName: '@patternfly/react-tokens',
                    libraryDirectory: 'dist/js',
                   camel2DashComponentName: false
                })
            ]
        })
  }

你知道我还需要更新什么,或者我可以检查什么,以确保这个转换器按照我的预期工作吗?

编辑:对旧的导入的引用消失了,但我之前没有注意到新的导入也被转换了:例如从foobarfoobar_1

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-02-12 04:18:01

TypeScript编译器有四个主要阶段--解析、绑定、类型检查和发出。绑定是标识符之间的关系被解析的地方,但转换发生在“发出”阶段。所以,当你转换的时候已经太晚了,编译器已经弄清楚了它要转换的标识符。

一种方法是遍历文件中的所有节点,找到与导入中的一个节点匹配的标识符,然后通过在该节点的访问器中返回context.factory.createIdentifier(node.escapedText)来重新创建这些标识符。这将使编译器在发出时保留节点的原样。

不过,问题可能是找出文件中的哪些标识符引用了命名的导入标识符。通常,我不建议在转换中使用类型检查器,因为当文件上发生多个转换时,类型检查器可能会导致意外的结果,但是您可以先检查标识符的escapeText是否匹配,然后检查typeChecker.getSymbolAtLocation(node)?.declarations[0]是否等于原始导入声明中找到的命名导出标识符。或者,我认为您必须实现自己的作用域分析。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66161672

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档