【问题标题】:Importing external module with ES6 syntax and absolute path使用 ES6 语法和绝对路径导入外部模块
【发布时间】: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.json 和 gulpfile.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']);

【问题讨论】:

    标签: import typescript


    【解决方案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/ 可能表明的那样,我有许多共享的、通用的实用程序函数,它们在我的项目中使用。计算每个给定文件需要达到根目录的../ 的数量是丑陋和混乱的,并且使重新组织文件不必要地痛苦。我绝对坚持我的坚持,即绝对路径在这里是必要的。对于我的文件夹或我的子文件夹中的内容,我可以看到相对路径的优势,但是一旦您必须上下不同的分支,就不会。
      猜你喜欢
      • 2015-08-01
      • 1970-01-01
      • 2020-12-30
      • 1970-01-01
      • 2015-12-06
      • 1970-01-01
      • 2012-08-27
      • 2020-10-27
      • 1970-01-01
      相关资源
      最近更新 更多