У меня есть установка с webpack + typescript (используя ts-loader).
Чтобы включить разделение кода с помощью веб-пакета, вы должны установить модуль esnext в tsconfig:
// tsconfig.json
{
"compilerOptions": {
"module": "esnext"
// other configuration ...
}
}
Я пытаюсь передать this
в качестве параметра в один из моих файлов. Он работает на node.js, который работает с индивидуально скомпилированными файлами с использованием собственного компилятора typescript, но проблема в следующем:
в вебпаке this
заменяется на undefined
Я сократил его до этой простой настройки:
Исходный код машинописного текста
export var this2 = this;
Выход tsc
:
export var this2 = this;
Выход веб-пакета:
/*!**********************!*\
!*** ./src/index.ts ***!
\**********************/
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "this2": () => (/* binding */ this2)
/* harmony export */ });
var this2 = undefined;
/******/ })()
;
Это происходит даже тогда, когда в файл экспортируется много других вещей (так что он не просто пуст и поэтому сводится к неопределенным)
Я не уверен на 100%, в чем проблема. Но обратите внимание, что это происходит нет с той же настройкой без машинописного текста (то есть веб-пакет + исходный код javascript + модуль = esnext) ни происходит ли это при компиляции машинописного текста в javascript для nodejs с tsc
.
Интересно, в чем проблема и является ли это ожидаемым поведением по какой-либо причине.
Я хочу, чтобы файл где-то регистрировал все экспорты этого файла, не импортируя его (другой файл не знает о его существовании). Но такое поведение, похоже, делает невозможным доступ к экспорту файлов и передачу их функции
минимальная настройка воспроизведения
См. этот живая настройка stackblitz
Запустите webpack
или tsc
в терминале, чтобы воссоздать выходные данные в /webpack
и /tsc
.
this
на верхнем уровне модуля ESM имеет значение undefined
. Это согласно спецификации (связь). Так что Webpack просто делает то, что говорит спецификация.
Если вы хотите, чтобы значение this
было на верхнем уровне немодульного скрипта, используйте новый (выходной) globalThis
(спец. | МДН).
В комментарии (и в вашем вопросе!) вы сказали:
I would like to access all the files' exports like this usually does in commonjs
Вы можете сделать это удивительным образом: получив объект пространства имен модуля из... самого модуля! Скажите, что вы делаете это в mod.js
. Вы можете получить объект пространства имен модуля для самого модуля, выполнив:
// *IN* `mod.js` itself
import * as mod from "./mod.js";
mod
будет ссылаться на объект, который имеет свойства для всех экспортов модуля (экспорт по умолчанию будет иметь имя свойства default
). Вот полный пример:
export const a = 42;
export const fn = () => { };
import * as mod from "./mod.js";
console.info(mod.a); // 42
console.info(typeof mod.fn) // "function"
Тем не менее, если вы хотите передавать вещи как единое целое, вы можете рассмотреть возможность явного создания объекта и его экспорта. Это зависит от варианта использования.
@Флион - А! Извините, вы упомянули в вопросе, что вы пытались сделать с this
, но я пропустил это. В ESM есть способ сделать это (я обновил ответ), хотя вместо этого вы можете подумать о написании объекта, если хотите передать его таким образом.
Идеальный! Очень проницательно. Спасибо за четкий ответ, именно то, что я искал.
Спасибо за эту ясность. Я этого не знал. Как бы я использовал
globalThis
? Если я регистрирую globalThis из файла, он регистрирует объект окна. Я хотел бы получить доступ ко всем экспортируемым файлам, как это обычно делаетthis
в commonjs