2015-10-23 4 views
5

Так у меня есть проект, который выглядит примерно так:Импорт внешнего модуля с синтаксисом ES6 и абсолютный путь

 
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
  • /src/utilities/common
  • /app/src/utilities/common

Ни одна из этих работ. Относительный путь ../utilities/common действительно работает, но относительные пути для общих модулей - это кошмар обслуживания.

Возможно, стоит отметить, что я только что обновился с TS 1.5 до 1.6: с использованием utilities/common работал в 1.5. Однако я не могу найти упоминания о разрыве изменений в этих строках в 1.6 примечаниях.

Я упоминаю gulpfile.ts и другие папки, потому что в конечном итоге я хочу, чтобы Gulp получал файлы TS от src и помещал скомпилированные JS-файлы в bin. Я достаточно уверен, что правильно настроил Gulp для этого, используя gulp-typescript, но для завершения, вот мои tsconfig.json и 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']); 
    

ответ

2

Наконец-то это решило. По What's New, 1.6 изменилось разрешение модуля, чтобы вести себя как Узел. Я еще не исследовал разрешение модуля Node, чтобы определить, возможно ли исправить это поведение, но я нашел обходное решение:

Старое поведение может быть вызвано, указав "moduleResolution": "classic" в tsconfig.json.

1

разрешение модуля выполняется относительно текущего файла, если путь начинается с ./ или ../.

Вот краткий пример использования:

/ 
/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. В моем случае я нацелен на ES5 с модулями UMD.

It Works!

Вы также можете разрешить модуль, если он может быть найден путем обхода вверх из текущего местоположения (это особенность NodeJS). Таким образом, вы можете импортировать thing.ts в submodule.ts с помощью:

import {something} from 'thing'; 

Разрешитель проверит текущую папку, а затем родителя, то родитель родителя ... и так далее.

Абсолютный против относительной Путей

Когда дело доходит до ссылки на веб-страницах, я согласен с вами, что абсолютные пути легче поддерживать, особенно там, где ресурсы распределяются на нескольких уровнях.

Когда речь заходит о модулях, я не уверен, что вижу ту же проблему обслуживания, что и пути, указанные здесь, «относительно файла, который содержит оператор импорта», по отношению к веб-странице. Интересно, может ли это быть применение очень разумного правила в неправильном месте.

+0

Я не вижу, чтобы последний вариант работал. – KRyan

+0

Перемещенные комментарии в ответ. – Fenton

+0

Ваш скриншот соответствует тому, что я ищу для достижения ('' src' на пути даст мне проблемы позже, но это не часть этого вопроса), но VS Code дает мне ошибку для этой же настройки. Я использую версию 0.9.1, с TypeScript 1.6.2; это то же самое с вами? – KRyan

Смежные вопросы