首页 文章

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

提问于
浏览
5

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

app/
  bin/
  lib/
  src/
    main/
      submodule.ts
    utilities/
      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-typescript 为此正确配置了Gulp,但为了完成起见,这里是我的 tsconfig.jsongulpfile.js .

  • tsconfig.json
{
    "compilerOptions": {
        "module": "commonjs",
        "target": "es5",
        "experimentalDecorators": true,
        "emitDecoratorMetadata": true,
        "noEmitOnError": true
    },
    "filesGlob": [
        "./**/*.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 merge = require('merge2');
var path  = require('path');

var tsProject = ts.createProject('src/tsconfig.json', { noExternalResolve: true });

gulp.task('html', function () {
    gulp.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 () {
    gulp.src([
            'src/**/*.less',
        ])
        .pipe(sourcemaps.init())
        .pipe(less())
        .pipe(sourcemaps.write())
        .pipe(gulp.dest('bin'))
});

gulp.task('default', ['html', 'typescript', 'less']);

2 回答

  • 1

    终于解决了这个 . 根据What's New,1.6更改了模块分辨率,表现得像Node 's. I have not yet investigated Node' s模块分辨率,以确定是否可以使用该行为进行修复,但我找到了一个解决方法:

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

  • 3

    如果路径以 ./../ 开头,则相对于当前文件执行模块分辨率 .

    这是一个使用的快速示例:

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

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

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

    您还可以使用以下根路径(请注意,此处没有前导 / 或任何 . ):

    import {common} from 'src/utilities/common';
    

    这在Visual Studio代码中适用于我, src 的父文件夹作为工作文件夹打开 . 在我的情况下,我使用UMD模块定位ES5 .

    It Works!

    如果可以通过从当前位置向上遍历找到模块(这是NodeJS的一个功能),也可以解析模块 . 所以你可以使用以下方法将 thing.ts 导入 submodule.ts

    import {something} from 'thing';
    

    解析器将检查当前文件夹,然后检查父项,然后检查父项的父项......依此类推 .

    绝对与相对路径

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

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

相关问题