Должен ли index.ts быть разрешен TypeScript как файл модуля по умолчанию?

Я пытаюсь заставить работать разрешение модуля в машинописном тексте.

Если у меня есть:

/modulename/index.ts

должно ли это быть решено:

import * as modulename from "modulename"

?

Я не могу заставить его работать. Но

import * as modulename from "modulename/index"

работает хорошо.

Изменить

как мне рекомендовал aluan-haddad, необходимо правильно настроить tsc.

Это сработало для меня:

{
   ...
   "baseUrl": ".",
   "module": "commonjs",
   "moduleResolution": "node",
   ...
}

Изменить

Обратите внимание, что эта конфигурация не работает при использовании с VS. Если он помещен во внешний файл tsconfig, компиляция работает хорошо, но языковая служба не может с этим справиться. Если он помещен в msconfig (csporj), происходит сбой компиляции и языковой службы.

Только одно решение, которое я нашел работающим на 100%, это создать что-то вроде:

src
   node_modules
      module_being_currently_developed
         submodules

В этом случае разрешение модуля работает правильно.


person Fis    schedule 17.05.2017    source источник
comment
Это локальный модуль? Если это так, я думаю, что это должен быть относительный путь, например import * as m from "./modulename".   -  person Aaron Beall    schedule 17.05.2017
comment
В настоящее время это локальный модуль, но я хочу поместить его в npm позже. поэтому в основном я хочу смоделировать его в папке node_modules.   -  person Fis    schedule 17.05.2017
comment
Будьте осторожны, потому что, как отмечено в моем ответе, baseUrl не является родной концепцией NodeJS, и поэтому вам понадобится что-то вроде Webpack или SystemJS для загрузки из него. Вы можете рассмотреть возможность добавления заглушки package.json и использования ссылки npm, если вы ориентируетесь на NodeJS на сервере.   -  person Aluan Haddad    schedule 17.05.2017
comment
Да, мне нужно сначала заставить его работать в IDE, а потом я как-нибудь справлюсь. В конце концов, я нацелен на amd, поэтому я как-нибудь справлюсь с этим. Я просто хотел избежать того, чтобы этот индекс был везде. Большое спасибо.   -  person Fis    schedule 17.05.2017
comment
Не проблема. RequireJS — отличный, проверенный временем инструмент. Вы обнаружите, что опция --paths также очень полезна с загрузчиком AMD или System.register. ГЛ ХФ!   -  person Aluan Haddad    schedule 17.05.2017
comment
Мне нужно написать собственный загрузчик/упаковщик модулей для моих целей;)   -  person Fis    schedule 17.05.2017
comment
@ Это непростая задача. Есть несколько довольно гибких загрузчиков, которые вы, вероятно, можете использовать. Конечно, было бы забавно написать загрузчик, но это ни в коем случае не тривиально, так что удачи вам.   -  person Aluan Haddad    schedule 18.05.2017
comment
Загрузчик будет легким, но я боюсь упаковщика... Спасибо.   -  person Fis    schedule 18.05.2017


Ответы (2)


В первую очередь это зависит от флага --moduleResolution (compilerOptions.moduleResultion в tsconfig.json).

Автоматическое преобразование каталога в файл с именем index в этом каталоге является соглашением NodeJS. Это соглашение распространилось на разработку на стороне клиента, но, тем не менее, остается соглашением. Он не является частью спецификации модуля ECMAScript или спецификации AMD.

При указании --moduleResolution node TypeScript будет следовать этому соглашению.

Кроме того, когда для флага --module (compilerOptions.module в tsconfig.json) установлено значение commonjs, это соглашение применяется автоматически даже при отсутствии флага --moduleResolution.

Обратите внимание, что этот параметр применяется как к коду приложения, так и к зависимостям в таких каталогах, как node_modules, jspm_packages и bower_components.

Хотя это наиболее целесообразно для проектов CommonJS, установка --moduleResolution node может быть выгодна в других форматах модулей, поскольку она помогает в разрешении зависимостей, а также позволяет избежать некоторых ловушек, связанных с альтернативным режимом разрешения classic.

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

Несмотря на склонность CommonJS к настройкам --moduleResolution node, я по-прежнему предпочитаю и рекомендую, хотя я не использую CommonJS, Webpack или Browserify в браузере (когда я могу их избежать).

Мой любимый загрузчик — SystemJS, а менеджер пакетов — JSPM, но я все же предпочитаю использовать схему разрешения узлов, потому что она упрощает импорт зависимостей, отчасти благодаря автоматической настройке JSPM загрузчика SystemJS.

Теперь давайте перейдем к --baseUrl применительно к вашему сценарию.

Вы пытаетесь импортировать локальный модуль как

import * as modulename from "modulename";

и установили --module commonjs и --baseUrl / в попытке импортировать локальный модуль, как если бы это был сторонний пакет, чтобы подготовить вашу кодовую базу к ее разделению на отдельный пакет. Могу добавить, что это хорошее планирование, так что +10 за это!

Однако, если вы планируете использовать модули CommonJS (чего я снова не советую делать только для браузерных приложений), вам определенно следует установить для "baseUrl" значение ".", а не "/". Даже в этом случае такие инструменты, как Native NodeJS require function, не поддерживают концепции baseUrl, возникшие в мире инструментов браузера. Однако Webpack поддерживает его.

В любом случае, чтобы загружать модули, которые являются частью вашего собственного исходного кода, используя спецификатор модуля, который не является относительным или абсолютным URL-адресом, я рекомендую следующее независимо (помните о требованиях к загрузчику!):

  1. Установите "baseURl" на "."
  2. Установите "moduleResolution" на "node",
  3. Установите "module" явно на "commonjs", "system" или "amd" (я не советую "umd").
  4. Если вы не используете "commonjs" под узлом, рассмотрите возможность использования "paths", так как это позволяет выполнить очень сложную реструктуризацию.
person Aluan Haddad    schedule 17.05.2017
comment
У меня есть baseUrl: /, module: commonjs, moduleResolution: node, и он все еще не работает :( - person Fis; 17.05.2017
comment
baseUrl следует использовать только вместе с commonjs в проектах Webpack или, возможно, Browserify. Никогда не проектируйте NodeJS. Даже тогда должно быть не /, а скорее.. - person Aluan Haddad; 17.05.2017
comment
Это локальный модуль, который вам нужен, или зависимость? - person Aluan Haddad; 17.05.2017
comment
В настоящее время это локальный модуль, но я хочу поместить его в npm позже. поэтому в основном я хочу смоделировать его в папке node_modules. - person Fis; 17.05.2017
comment
Попался. позвольте мне добавить некоторую информацию об этом - person Aluan Haddad; 17.05.2017
comment
он начал работать, когда я использовал baseUrl: ., я думаю, / разрешен как корневая папка. Спасибо за чаевые! - person Fis; 17.05.2017

Вы должны добавить косую черту в имя папки (модуля), это будет рассматривать index.ts как индекс папки.

import * as modulename from "modulename/"
person coderbuzz    schedule 01.06.2021