简体   繁体   English

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

[英]Importing external module with ES6 syntax and absolute path

So I have a project that looks something like this: 所以我有一个看起来像这样的项目:

app/
  bin/
  lib/
  src/
    main/
      submodule.ts
    utilities/
      common.ts
    main.ts
    tsconfig.json
  gulpfile.js

and app/src/main/submodule.ts needs to import app/src/utilities/common.ts . app/src/main/submodule.ts需要导入app/src/utilities/common.ts I am trying to use the ES6 syntax for this. 我正在尝试使用ES6语法。 Thus I expect something like this in submodule.ts : 因此我希望在submodule.ts这样的东西:

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

Where the root / is app/src/ since that is where tsconfig is found. 其中root /app/src/因为这是找到tsconfig的地方。 Yes, app/src/utilities/common.ts does export a module named common . 是的, app/src/utilities/common.ts确实导出了一个名为common的模块。

The problem is that I get "cannot find module '/utilities/common'" errors. 问题是我得到“找不到模块'/ utilities / common'”错误。 I have tried a variety of things: 我尝试过各种各样的事情:

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

None of these work. 这些都不起作用。 A relative path of ../utilities/common does work, but relative paths for common modules is a maintenance nightmare. ../utilities/common的相对路径确实有效,但常见模块的相对路径是维护噩梦。

It may be worth noting that I just updated from TS 1.5 to 1.6: using utilities/common had worked in 1.5. 值得注意的是,我刚刚从TS 1.5更新到1.6:使用utilities/common已经在1.5中工作。 I cannot find any mention of a breaking change along these lines in the 1.6 notes, though. 然而,我在1.6音符中找不到任何关于这些线路的突破性变化。

I mention the gulpfile.ts and other folders because ultimately I want Gulp to get the TS files from src and put the compiled JS files in bin . 我提到了gulpfile.ts和其他文件夹,因为最终我希望Gulp从src获取TS文件并将已编译的JS文件放入bin I am reasonably confident that I have correctly configured Gulp for this, using gulp-typescript , but for completion's sake, here are my tsconfig.json and gulpfile.js . 我有理由相信我已经使用gulp-typescript tsconfig.json正确配置了Gulp,但为了完成起见,这里是我的tsconfig.jsongulpfile.js

  • tsconfig.json

    \n{ {\n    "compilerOptions": { “compilerOptions”:{\n        "module": "commonjs", “module”:“commonjs”,\n        "target": "es5", “目标”:“es5”,\n        "experimentalDecorators": true, “experimentalDecorators”:是的,\n        "emitDecoratorMetadata": true, “emitDecoratorMetadata”:是的,\n        "noEmitOnError": true “noEmitOnError”:是的\n    }, },\n    "filesGlob": [ “filesGlob”:[\n        "./**/*.ts", “./**/*.ts”\n        "!./typings/**/*.ts" “!./分型/ ** / *。TS”\n    ] ]\n} } 
  • gulpfile.js

    \nvar gulp = require('gulp'); var gulp = require('gulp');\nvar ts = require('gulp-typescript'); var ts = require('gulp-typescript');\nvar less = require('gulp-less'); var less = require('gulp-less');\nvar sourcemaps = require('gulp-sourcemaps'); var sourcemaps = require('gulp-sourcemaps');\n\nvar merge = require('merge2'); var merge = require('merge2');\nvar path = require('path'); var path = require('path');\n\nvar tsProject = ts.createProject('src/tsconfig.json', { noExternalResolve: true }); var tsProject = ts.createProject('src / tsconfig.json',{noExternalResolve:true});\n\ngulp.task('html', function () { gulp.task('html',function(){\n    gulp.src([ gulp.src([\n            'src/**/*.html', 'SRC / ** / *。HTML',\n        ]) ])\n        .pipe(gulp.dest('bin')); .pipe(gulp.dest( '仓'));\n}); });\n\ngulp.task('typescript', function () { gulp.task('typescript',function(){\n    tsProject.src() tsProject.src()\n        .pipe(sourcemaps.init()) .pipe(sourcemaps.init())\n        .pipe(ts(tsProject)) .pipe(TS(tsProject))\n        .js .js文件\n        .pipe(sourcemaps.write()) .pipe(sourcemaps.write())\n        .pipe(gulp.dest('bin')); .pipe(gulp.dest( '仓'));\n}); });\n\ngulp.task('less', function () { gulp.task('less',function(){\n    gulp.src([ gulp.src([\n            'src/**/*.less', 'SRC / ** / *。少',\n        ]) ])\n        .pipe(sourcemaps.init()) .pipe(sourcemaps.init())\n        .pipe(less()) .pipe(以下())\n        .pipe(sourcemaps.write()) .pipe(sourcemaps.write())\n        .pipe(gulp.dest('bin')) .pipe(gulp.dest( '本'))\n}); });\n\ngulp.task('default', ['html', 'typescript', 'less']); gulp.task('default',['html','typescript','less']);\n

Finally solved this. 终于解决了这个。 Per What's New , 1.6 changed module resolution to behave like Node's. Per What's New ,1.6改变了模块分辨率,表现得像Node一样。 I have not yet investigated Node's module resolution to determine if a fix is possible using that behavior, but I have found a workaround: 我还没有调查Node的模块分辨率来确定是否可以使用该行为进行修复,但我找到了一个解决方法:

The old behavior can be triggered by specifying "moduleResolution": "classic" in tsconfig.json . 可以通过在tsconfig.json指定"moduleResolution": "classic" tsconfig.json "moduleResolution": "classic"来触发旧行为。

Module resolution is performed relative to the current file if the path starts with ./ or ../ . 如果路径以./../开头,则相对于当前文件执行模块分辨率。

Here is a quick example using: 这是一个使用的快速示例:

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

So the correct statement to import common.ts into submodule.ts would be: 所以将common.ts导入submodule.ts的正确语句是:

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

You can also use the following root-path (note that there is no leading / or any . s here): 您还可以使用以下根路径(请注意,此处没有前导/或任何. ):

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

This works for me in Visual Studio code, with the parent folder of src opened as the working folder. 这在Visual Studio代码中适用于我, src的父文件夹作为工作文件夹打开。 In my case I am targeting ES5 with UMD modules. 在我的情况下,我使用UMD模块定位ES5。

有用!

You can also resolve a module if it can be found by traversing up from the current location (this is a feature of NodeJS). 如果可以通过从当前位置向上遍历找到模块(这是NodeJS的一个功能),也可以解析模块。 So you can import thing.ts into submodule.ts using: 所以你可以使用以下方法将thing.ts导入submodule.ts

import {something} from 'thing';

The resolver will check the current folder, then the parent, then the parent's parent... and so on. 解析器将检查当前文件夹,然后检查父项,然后检查父项的父项......依此类推。

Absolute vs Relative Paths 绝对与相对路径

When it comes to links on web pages, I'm in agreement with you that absolute paths are easier to maintain, especially where resources are shared at multiple levels. 当谈到网页上的链接时,我同意你的观点,即绝对路径更容易维护,尤其是在多个级别共享资源的情况下。

When it comes to modules, I'm not sure I see the same maintenance problem as the paths here are "relative to the file that the import statement appears in" not relative to the web page. 说到模块,我不确定我是否看到了相同的维护问题,因为这里的路径是“相对于导入语句出现的文件”而不是相对于网页。 I wonder if this may be the application of a very sensible rule in the wrong place. 我想知道这是否可能是在错误的地方应用一个非常明智的规则。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM