自定义模块的相对与非相对模块导入

ben*_*inz 4 javascript typescript ecmascript-6

更新[09/12/2017 16:58 EST]

在此问题的底部添加了为什么我犹豫是否将本机支持的非相对导入与我自己的模块一起使用的原因。

更新[09/12/2017 12:58 EST]:

根据请求,我使下面的文件结构反映了我的实际用例。这是一个嵌套的视图模块,它请求目录树上某处的实用程序模块。


每个请求

在 TypeScript 和 ES6 中,都可以通过以下方式导入自定义模块

// Relative
import { numberUtil } from './number_util';
// OR
// Non-relative
import { numberUtil } from 'number_util';
Run Code Online (Sandbox Code Playgroud)

根据 TypeScript 文档(链接),应该:

...为您自己的模块使用相对导入,保证在运行时保持其相对位置。

... 在导入任何外部依赖项时使用非相对路径。

我的问题是我有一个这样的项目结构:

project/
  |--utils
  |    |--number_util.ts
  |--views
  |    |--article_page
  |         |-- editor_view
  |                |--editor_text_area.ts
Run Code Online (Sandbox Code Playgroud)

当我包含utils/number_util在我的editor_text_area模块中时,import 语句如下所示:

import { numberUtil } from './../../../utils/number_util';
Run Code Online (Sandbox Code Playgroud)

这很长而且不可读,最糟糕的是,难以维护:每当我需要移动时editor_text_area,我将不得不更新每个这些相对路径,同时我可以使用非相对方式

import { numberUtil } from 'utils/number_util';
Run Code Online (Sandbox Code Playgroud)

有没有人对如何最好地进行模块导入以实现最高的可读性和可维护性有任何建议?


但是使用非相对方式会带来一个问题(官方文档不推荐这种方式除外):如果我安装了一个npm与我正在导入的模块同名的模块怎么办?在这一点上,它不如上面提到的更丑陋的替代方案安全

rap*_*sse 5

根据您的项目工具和结构,您有一些选择。

A)您可以将部分依赖项作为独立模块发布,也许在私有注册表中。然后,您可以使用 npm 安装它们,并像其他任何外部依赖项一样要求它们。

B)许多模块系统支持某种路径映射。所述VUE-JS的WebPack模板使用的WebPack别名功能到集@的源代码根。TypeScript 也支持路径映射。介绍该映射后,您可以使用

import { numberUtil } from '@/utils/number_util';
Run Code Online (Sandbox Code Playgroud)

这种方法基本上为您的模块引入了一个私有命名空间。这是安全的,因为您只能隐藏名称@无效的 npm 模块,因此无法存在。

对于您的示例,您必须在以下条目中包含以下条目compilerOptions

"baseUrl": ".",
"paths": {
    "@/*": ["*"]
}
Run Code Online (Sandbox Code Playgroud)

或者,如果您只想从 导入模块utils,您可以将映射更改为"@/*": ["utils/*"]并使用'@/number_util'.

C)另一件需要考虑的事情是改进你的项目结构。根据您的实际项目,在某一点或另一点应用外观模式可能是有意义的。也许依赖注入editor_text_area而不是让它自己导入。