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

ne5o7dgx  于 6个月前  发布在  TypeScript
关注(0)|答案(7)|浏览(71)
  • 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
const f = 1234;
module.exports = f;
  1. require it
const f = require('./above-file');
console.log(f);
  1. console.log中的f在Find All References中不显示跨文件的引用。如果您从模块文件中查找所有引用,则可以找到跨文件的引用。
    然而,
  2. module.exports.foo something
const f = 1234;
module.exports.foo = f;
  1. require it
const {foo} = require('./above-file');
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 :

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

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

/// <reference path='fourslash.ts'/>

// @allowJs: true

// @Filename: /a.ts
////function [|{| "isWriteAccess": true, "isDefinition": true |}x|]() {};
////export = [|x|];

// @Filename: /b.js
////const [|{| "isWriteAccess": true, "isDefinition": true |}x|] = require("./a");
////[|x|];

const [r0, r1, r2, r3] = test.ranges();
verify.referenceGroups(r2, [/*todo*/]);
57hvy0tb

57hvy0tb3#

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

/// <reference path='fourslash.ts'/>

// @allowJs: true

// @Filename: /a.js
////function [|{| "isWriteAccess": true, "isDefinition": true |}x|]() {};
////module.exports = [|x|];

// @Filename: /b.ts
////import [|{| "isWriteAccess": true, "isDefinition": true |}x|] = require("./a");
////[|x|];

const [r0, r1, r2, r3] = test.ranges();
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之前需要先修复它。

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

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

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

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

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

相关问题