TypeScript 在不使用默认的CommonJS导出的情况下,从需要文件中查找所有引用到模块文件仅对模块文件有效,

ne5o7dgx  于 9个月前  发布在  TypeScript
关注(0)|答案(7)|浏览(106)
  • 2018年2月28日 4:58@Hoishin*

我所说的“默认的CommonJS导出”是指module.exports = something,而不是module.exports.foo = somethingmodule.exports = {foo: something}

它可能属于microsoft/vscode#21507,但我认为它有点不同。

  • VSCode版本:1.20.1
  • 操作系统版本:macOS High Sierra版本10.13.3

重现步骤:

  1. module.exports something
  1. const f = 1234;
  2. module.exports = f;
  1. require it
  1. const f = require('./above-file');
  2. console.log(f);
  1. console.log中的f在Find All References中不显示跨文件的引用。如果您从模块文件中查找所有引用,则可以找到跨文件的引用。
    然而,
  2. module.exports.foo something
  1. const f = 1234;
  2. module.exports.foo = f;
  1. require it
  1. const {foo} = require('./above-file');
  2. console.log(foo);
  1. console.log中的foo在Find All References中确实显示了跨文件的引用。如果您从模块文件中查找所有引用,则可以找到跨文件的引用。
    当所有扩展都被禁用时,此问题是否仍然存在?:是的
ruoxqz4g

ruoxqz4g1#

在控制台的console.log中的f没有显示在Find All References中的所有文件之间的引用。如果你从模块文件中使用Find All References,你可以找到跨文件的引用。
这里的问题是,find all references显示了f./above-file中。f有一个不同的名字,不应该出现在引用集中。
在控制台的console.log中的foo确实显示了跨文件的引用。如果你从模块文件中使用Find All References,你可以找到跨文件的引用。这很有意义,因为你是在引用模块上的属性。

xxhby3vn

xxhby3vn2#

importTracker 中,我将以下内容添加到了 isNodeImport :

  1. case SyntaxKind.VariableDeclaration:
  2. return { isNamedImport: false };

但是在 checker.getImmediateAliasedSymbol(symbol);getImport 中失败了。问题在于 const x = require("./x") 没有给我们一个导出的别名,它只是给了我们一个与 x 导出相同类型的变量。从导出到导入的工作是可行的,因为检测导入是基于被导入的文件。但是反向操作不起作用,除非我们有一种方法来获取原始符号。
@rbuckton@sandersn 我们为什么不在 const x = require("./x") 创建别名符号,而是在 import x = require("./x") 创建呢?
我进行了测试:

  1. /// <reference path='fourslash.ts'/>
  2. // @allowJs: true
  3. // @Filename: /a.ts
  4. ////function [|{| "isWriteAccess": true, "isDefinition": true |}x|]() {};
  5. ////export = [|x|];
  6. // @Filename: /b.js
  7. ////const [|{| "isWriteAccess": true, "isDefinition": true |}x|] = require("./a");
  8. ////[|x|];
  9. const [r0, r1, r2, r3] = test.ranges();
  10. verify.referenceGroups(r2, [/*todo*/]);
展开查看全部
57hvy0tb

57hvy0tb3#

以下测试用例在当前(未修改)的情况下因找不到符号而崩溃:

  1. /// <reference path='fourslash.ts'/>
  2. // @allowJs: true
  3. // @Filename: /a.js
  4. ////function [|{| "isWriteAccess": true, "isDefinition": true |}x|]() {};
  5. ////module.exports = [|x|];
  6. // @Filename: /b.ts
  7. ////import [|{| "isWriteAccess": true, "isDefinition": true |}x|] = require("./a");
  8. ////[|x|];
  9. const [r0, r1, r2, r3] = test.ranges();
  10. verify.referenceGroups(r2, [/*todo*/]);
eqfvzcg8

eqfvzcg84#

#23570 是否修复了这个问题?它将 module.exports 设置为一个别名,就像 export= 一样。

xsuvu9jc

xsuvu9jc5#

@sandersn That fixes the second example, but it looks like const x = require("./a"); is still not an alias. So it will still crash in the first example (given the modification to isNodeImport ).

sqyvllje

sqyvllje6#

我认为修复 #25533 可以解决这个问题。

2w3kk1z5

2w3kk1z57#

在这个问题上,Typescript的行为是如此的糟糕,以至于在修复Javascript之前需要先修复它。

  1. // @Filename: welove.ts
  2. const g = 4567;
  3. export = g;
  4. // @Filename: app.tsx
  5. import good = require('./welove')
  6. console.log(good/*1*/)

/*1*/ 处查找所有引用,找到了四个引用,这是有争议的,因为 ggood 有不同的名称。在 /*1*/ 处重命名所有四个引用,这似乎很糟糕,因为 ggood 不是同一个名称,而 welove.ts 可能是一个d.ts文件,重命名会导致中断。

  1. // @Filename: welove.ts
  2. const g = 4567;
  3. export const good = g;
  4. // @Filename: app.tsx
  5. import { good } from './welove'
  6. console.log(good/*1*/)

在这里,在(1)处查找所有引用找到了最后三行,这看起来没问题。但是即使导入是 import { good as go } ,它也会出现错误,与 export= 示例中的错误相同。重命名功能完全无法使用。在(1)处重命名最后一行,将导入重命名为 import { good as go } ,然后错误地重命名了 export const go = g

这个问题可能在VS的一些版本中已经修复了,但在VS Code和emacs中仍然存在问题。我会看看是否已经有现有的bug报告。

展开查看全部

相关问题