【问题标题】:Should the index.ts be resolved by TypeScript as default module file?TypeScript 是否应该将 index.ts 解析为默认模块文件?
【发布时间】:2017-10-17 03:35:18
【问题描述】:

我正在尝试使用 typescript 下的模块分辨率。

如果我有:

/modulename/index.ts

应该通过以下方式解决:

import * as modulename from "modulename"

?

我无法让它工作。但是

import * as modulename from "modulename/index"

效果很好。

编辑

aluan-haddad 建议我正确配置 tsc。

这个对我有用:

{
   ...
   "baseUrl": ".",
   "module": "commonjs",
   "moduleResolution": "node",
   ...
}

编辑

请注意,此配置在与 VS 一起使用时不起作用。如果将其放在外部 tsconfig 文件中,则编译效果很好,但语言服务无法处理。如果它同时放在 msconfig (csporj) 中,编译和语言服务都会失败。

我发现只有一个可以 100% 工作的解决方案是创建类似的东西:

src
   node_modules
      module_being_currently_developed
         submodules

在这种情况下,模块解析工作正常。

【问题讨论】:

  • 这是本地模块吗?如果是这样,我认为它应该是像import * as m from "./modulename" 这样的相对路径。
  • 它目前是一个本地模块,但我想稍后把它放到npm。所以基本上,我想在 node_modules 文件夹下模拟它。
  • 要小心,因为正如我在回答中指出的那样,baseUrl 不是原生 NodeJS 概念,因此您需要从它加载 Webpack 或 SystemJS 之类的东西。如果您的目标是服务器上的 NodeJS,您可能需要考虑添加一个存根 package.json 并使用 npm 链接
  • 是的,我需要先让它在 IDE 中工作,然后我会以某种方式处理它。我最终以“amd”为目标,所以我会以某种方式处理它。我只是想避免到处都有那个索引。非常感谢。
  • 没问题。 RequireJS 是一个优秀的、久经考验的真正工具。您会发现--paths 选项对 AMD 或 System.register 加载程序也很有帮助。 GL HF!

标签: typescript commonjs es6-modules


【解决方案1】:

它主要取决于--moduleResolution 标志(tsconfig.json 中的compilerOptions.moduleResultion

将目录自动解析为该目录中名为 index 的文件是 NodeJS 约定。这个约定传播到客户端开发,但它仍然是一个约定。它不是 ECMAScript 模块规范或 AMD 规范的一部分。

当指定--moduleResolution node 时,TypeScript 将遵循此约定。

此外,当--module 标志(tsconfig.json 中的compilerOptions.module)设置为commonjs 时,即使没有--moduleResolution 标志,也会自动应用此约定。

请注意,该设置适用于应用程序代码和目录中的依赖项,例如 node_modulesjspm_packagesbower_components

虽然它对 CommonJS 项目最有意义,但设置 --moduleResolution node 在其他模块格式中可能是有利的,因为它有助于解决依赖关系并避免替代 classic 解析模式带来的某些陷阱。

但请注意,RequireJS 和 SystemJS 等加载器不会自动在您的应用源代码中采用此约定,因此在导入您自己的应用代码时仍建议在模块说明符中使用显式索引文件。

尽管 CommonJS 倾向于 --moduleResolution node 设置,但我仍然更喜欢并推荐即使我不在浏览器中使用 CommonJS、Webpack 或 Browserify(当我可以避免它们时)。

我选择的加载器是 SystemJS,我选择的包管理器是 JSPM,但我仍然更喜欢使用节点解析方案,因为它使导入依赖项更容易,部分归功于 JSPM 对 SystemJS 加载器的自动配置。

现在,让我们继续讨论 --baseUrl,因为它适用于您的场景。

您正在尝试将本地模块导入为

import * as modulename from "modulename";

并设置了--module commonjs--baseUrl / 以尝试导入本地模块,就好像它是第三方包一样,以准备您的代码库以将其拆分为离散包。我可能会补充说,这是一个很好的计划,所以:+10!

但是,如果您打算使用 CommonJS 模块(我再次建议不要将其用于仅浏览器的应用程序),您绝对应该将您的 "baseUrl" 设置为 "." 而不是 "/"。即便如此,像 Native NodeJS require 函数这样的工具也不支持源自浏览器工具世界的 baseUrl 概念。然而,Webpack 确实支持它。

无论如何,要使用不是相对或绝对 URL 的模块说明符来加载属于您自己的源代码一部分的模块,我推荐以下方法(注意加载器要求!):

  1. "baseURl" 设置为"."
  2. "moduleResolution"设置为"node"
  3. "module" 明确设置为"commonjs""system""amd"(我建议不要使用"umd")。
  4. 如果不使用节点下的"commonjs",请考虑使用"paths",因为它允许进行一些非常复杂的重组。

【讨论】:

  • 我有 "baseUrl": "/", "module": "commonjs", "moduleResolution": "node" 但它似乎仍然无法正常工作:(
  • "baseUrl" 只能在 Webpack 或 Browserify 项目中与 "commonjs" 一起使用。从不使用 NodeJS 项目。即使这样,它也不应该是“/”,而是“.”。
  • 这是您需要或依赖的本地模块吗?
  • 它目前是一个本地模块,但我想稍后把它放到npm。所以基本上,我想在 node_modules 文件夹下模拟它。
  • 当我使用“baseUrl”时它开始工作:“。”,我认为“/”被解析为根文件夹。感谢您的提示!
【解决方案2】:

您必须在文件夹(模块)名称中添加一个斜杠,这会将 index.ts 视为文件夹索引。

import * as modulename from "modulename/"

【讨论】:

    猜你喜欢
    • 2021-07-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-28
    • 1970-01-01
    • 1970-01-01
    • 2018-11-10
    相关资源
    最近更新 更多