使用 webpack + typescript + module = "esnext" 更改为未定义
this is changed to undefined with webpack + typescript + module = "esnext"
我有一个带有 webpack + typescript 的设置(使用 ts-loader)。
要使用 webpack 启用代码拆分,you must set module to esnext in tsconfig:
// tsconfig.json
{
"compilerOptions": {
"module": "esnext"
// other configuration ...
}
}
我正在尝试将 this
作为我的一个文件中的参数传递。它适用于 node.js,它使用本机打字稿编译器在单独编译的文件上运行,但问题是:
在webpack中this
被替换为undefined
我已将其简化为这个简单的设置:
打字稿源代码
export var this2 = this;
tsc
的输出:
export var this2 = this;
Webpack 输出:
/*!**********************!*\
!*** ./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% 确定问题出在哪里。但请注意,这确实 不会 发生 使用没有打字稿的相同设置(所以 webpack + javascript source + module=esnext)nor 使用 tsc
.
将 typescript 编译为 javascript for nodejs 是否会发生这种情况
我想知道问题出在哪里,这是否出于某种原因是预期的行为。
我想要一个文件在某处注册该文件的所有导出,而不必导入它(另一个文件不知道它的存在)。但是这种行为似乎无法访问文件的导出并将它们传递给函数
最小复制设置
运行 webpack
或 tsc
在终端中重新创建 /webpack
和 /tsc
中的输出
ESM 模块顶层的 this
的值为 undefined
。这是每个规范 (link)。所以 Webpack 只是按照规范所说的去做。
如果您希望值 this
位于 non-module 脚本的顶层,请使用新的(ish)globalThis
(spec | MDN)。
在评论中(以及在您的问题中!)您说:
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.log(mod.a); // 42
console.log(typeof mod.fn) // "function"
就是说,如果您想像那样将事物作为一个单元传递,您可以考虑显式创建一个对象并导出该对象。这取决于用例。
我有一个带有 webpack + typescript 的设置(使用 ts-loader)。
要使用 webpack 启用代码拆分,you must set module to esnext in tsconfig:
// tsconfig.json
{
"compilerOptions": {
"module": "esnext"
// other configuration ...
}
}
我正在尝试将 this
作为我的一个文件中的参数传递。它适用于 node.js,它使用本机打字稿编译器在单独编译的文件上运行,但问题是:
在webpack中this
被替换为undefined
我已将其简化为这个简单的设置:
打字稿源代码
export var this2 = this;
tsc
的输出:
export var this2 = this;
Webpack 输出:
/*!**********************!*\
!*** ./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% 确定问题出在哪里。但请注意,这确实 不会 发生 使用没有打字稿的相同设置(所以 webpack + javascript source + module=esnext)nor 使用 tsc
.
我想知道问题出在哪里,这是否出于某种原因是预期的行为。
我想要一个文件在某处注册该文件的所有导出,而不必导入它(另一个文件不知道它的存在)。但是这种行为似乎无法访问文件的导出并将它们传递给函数
最小复制设置
运行 webpack
或 tsc
在终端中重新创建 /webpack
和 /tsc
this
的值为 undefined
。这是每个规范 (link)。所以 Webpack 只是按照规范所说的去做。
如果您希望值 this
位于 non-module 脚本的顶层,请使用新的(ish)globalThis
(spec | MDN)。
在评论中(以及在您的问题中!)您说:
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.log(mod.a); // 42
console.log(typeof mod.fn) // "function"
就是说,如果您想像那样将事物作为一个单元传递,您可以考虑显式创建一个对象并导出该对象。这取决于用例。