使用 ES6 语法和绝对路径导入外部模块

Posted

技术标签:

【中文标题】使用 ES6 语法和绝对路径导入外部模块【英文标题】:Importing external module with ES6 syntax and absolute path 【发布时间】:2016-01-23 09:13:55 【问题描述】:

所以我有一个看起来像这样的项目:

应用程序/ 仓/ 库/ 源/ 主要的/ 子模块.ts 公用事业/ common.ts main.ts tsconfig.json gulpfile.js

app/src/main/submodule.ts 需要导入app/src/utilities/common.ts。我正在尝试为此使用 ES6 语法。因此,我希望在submodule.ts 中有这样的内容:

import common from '/utilities/common';

/app/src/,因为这是找到tsconfig 的位置。是的,app/src/utilities/common.ts 确实导出了一个名为 common 的模块。

问题是我收到“找不到模块'/utilities/common'”错误。我尝试了很多方法:

utilities/common /src/utilities/common /app/src/utilities/common

这些都不起作用。 ../utilities/common 的相对路径确实有效,但常见模块的相对路径是维护的噩梦。

值得注意的是,我刚刚从 TS 1.5 更新到 1.6:使用 utilities/common 已经在 1.5 中工作。不过,我在 1.6 的注释中找不到任何关于这些方面的重大更改。

我提到gulpfile.ts 和其他文件夹,因为最终我希望Gulp 从src 获取TS 文件并将编译好的JS 文件放在bin 中。我有理由相信我已经正确配置了 Gulp,使用 gulp-typescript,但为了完整起见,这里是我的 tsconfig.jsongulpfile.js

tsconfig.json

“编译器选项”: “模块”:“commonjs”, “目标”:“es5”, “experimentalDecorators”:是的, “emitDecoratorMetadata”:真, “noEmitOnError”:真 , “文件全球”:[ "./**/*.ts", “!./typings/**/*.ts” ]

gulpfile.js

var gulp = require('gulp'); var ts = require('gulp-typescript'); var less = require('gulp-less'); var sourcemaps = require('gulp-sourcemaps'); var 合并 = 要求('merge2'); var path = require('path'); var tsProject = ts.createProject('src/tsconfig.json', noExternalResolve: true ); gulp.task('html', function () 吞咽.src([ 'src/**/*.html', ]) .pipe(gulp.dest('bin')); ); gulp.task('typescript', function () tsProject.src() .pipe(sourcemaps.init()) .pipe(ts(tsProject)) .js .pipe(sourcemaps.write()) .pipe(gulp.dest('bin')); ); gulp.task('less', function () 吞咽.src([ 'src/**/*.less', ]) .pipe(sourcemaps.init()) .pipe(少()) .pipe(sourcemaps.write()) .pipe(gulp.dest('bin')) ); gulp.task('default', ['html', 'typescript', 'less']);

【问题讨论】:

【参考方案1】:

终于解决了。根据What's New,1.6 更改了模块分辨率,使其表现得像 Node 的一样。我尚未调查 Node 的模块分辨率以确定是否可以使用该行为进行修复,但我找到了解决方法:

可以通过在tsconfig.json 中指定"moduleResolution": "classic" 来触发旧行为。

【讨论】:

【参考方案2】:

如果路径以./../ 开头,则相对于当前文件执行模块解析。

下面是一个简单的例子:

/
/src/
/src/thing.ts
/main/
/main/submodule.ts
/utilities/
/utilities/common.ts

因此,将common.ts 导入submodule.ts 的正确语句是:

import common from '../utilities/common';

您还可以使用以下根路径(注意这里没有前导 / 或任何 .s):

import common from 'src/utilities/common';

这适用于我在 Visual Studio 代码中,src 的父文件夹作为工作文件夹打开。就我而言,我的目标是带有 UMD 模块的 ES5。

如果可以通过从当前位置向上遍历找到一个模块,您也可以解析它(这是 NodeJS 的一个特性)。所以你可以将thing.ts 导入submodule.ts 使用:

import something from 'thing';

解析器将检查当前文件夹,然后是父级,然后是父级的父级......等等。

绝对路径与相对路径

对于网页上的链接,我同意你的观点,即绝对路径更易于维护,尤其是在多个级别共享资源的情况下。

当涉及到模块时,我不确定我是否看到相同的维护问题,因为这里的路径是“相对于导入语句出现的文件”而不是相对于网页。我想知道这是否可能是在错误的地方应用了一个非常明智的规则。

【讨论】:

将 cmets 移动到答案中。 您的屏幕截图符合我想要实现的目标(路径中的 src 稍后会给我带来麻烦,但这不是这个问题的一部分),但是 VS Code 给了我同样的错误设置。我使用的是 0.9.1 版,TypeScript 1.6.2;你也一样吗? 是 - Visual Studio Code 的 0.9.1,TypeScript 1.6.2。您的机器上是否还有其他版本的编译器可能会被拾取? 如果是这样,我希望它能够正常工作,因为它在我更新之前曾经工作过。我确实安装了(几个)其他版本的tsc,但 1.6 绝对是我路径中的版本,由 PowerShell 找到,并由 Visual Studio 2015 使用。我会尝试删除旧版本,看看它是否使事情突然起作用了,但我很怀疑。不幸的是,现在不能这样做。 将旧的 TypeScript 编译器放入回收站;不用找了。至于您在此处的最后一部分,正如名称 utilities/ 可能表明的那样,我有许多共享的、通用的实用程序函数,它们在我的项目中使用。计算每个给定文件需要达到根目录的../ 的数量是丑陋和混乱的,并且使重新组织文件不必要地痛苦。我绝对坚持我的坚持,即绝对路径在这里是必要的。对于我的文件夹或我的子文件夹中的内容,我可以看到相对路径的优势,但是一旦您必须上下不同的分支,就不会。

以上是关于使用 ES6 语法和绝对路径导入外部模块的主要内容,如果未能解决你的问题,请参考以下文章

在Python中以绝对路径或者相对路径导入文件(或模块)的方法

导入 JavaScript 时如何在 QML 中使用绝对路径?

模块的绝对导入相对导入

为特定模块编写测试时如何使用绝对导入路径

Python 包内的导入问题(绝对导入和相对导入)

NextJS、Storybook、SVG 和绝对导入路径