Import an 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 need to import app/src/utilities/common.ts . I am trying to use ES6 syntax for this. Therefore, I expect something like this in submodule.ts :

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

If the root of / is equal to app/src/ , since this is where tsconfig found. Yes, app/src/utilities/common.ts exports a module called common .

The problem is that I get "can not find module / utility / general errors". I tried different things:

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

None of these works. The relative path ../utilities/common works, but the relative paths for common modules are a maintenance nightmare.

It may be worth noting that I just upgraded TS 1.5 to 1.6: using utilities/common worked in 1.5. However, I cannot find mention of breaking the changes in these lines in 1.6 notes.

I mention gulpfile.ts and other folders because ultimately I want Gulp to get TS files from src and put the compiled JS files in bin . I am sure that for this I configured Gulp correctly using gulp-typescript , but for a complete download, here are my tsconfig.json and gulpfile.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']);
    
+5
source share
2 answers

Finally decided this. Per What's New , 1.6 changed the resolution of the module to behave like Node. I have not yet examined the resolution of the Node module to determine if a fix is ​​possible using this behavior, but I found a workaround:

You can invoke the old behavior by specifying "moduleResolution": "classic" in tsconfig.json .

+2
source

The resolution of the module is relative to the current file if the path starts with ./ or ../ .

Here is an example:

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

Thus, the correct instruction to import common.ts into submodule.ts would be:

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

You can also use the following root path (note that there is no lead / or any . ):

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

This works for me in Visual Studio code with the src parent folder open as a working folder. In my case, I am targeting ES5 with UMD modules.

It works!

You can also enable the module if it can be found by going from the current location (this is the NodeJS function). So you can import thing.ts into submodule.ts using:

 import {something} from 'thing'; 

The resolver will check the current folder, then the parent, then the parent parent ... etc.

Absolute versus Relative Paths

When it comes to links on web pages, I agree with you that absolute paths are easier to maintain, especially when resources are distributed at several levels.

When it comes to modules, I'm not sure that I see the same maintenance problem as the paths that refer here “relative to the file that the import statement is displayed” not to the web page. I wonder if this could be applying a very reasonable rule in the wrong place.

+1
source

Source: https://habr.com/ru/post/1234398/


All Articles