[英]Webpack code splitting breaks instanceof between chunks
tl:博士;
class ModuleInBundleA extends ModuleInBundleC { … }
window.moduleInBundleB.foo(new ModuleInBundleA())
class ModuleInBundleB {
public foo(bar: ModuleInBundleA|ModuleInBundleC|number) {
if (bar instanceof ModuleInBundleA || bar instanceof ModuleInBundleC) {
// always false
…
}
}
}
细节:
我正在尝试在主要具有旧代码库的项目上开始使用 TypeScript + Webpack 4.41.6。 基本上我想将几个小模块打包到包中,以便在不将整个项目移动到新的 js 堆栈的情况下进行软迁移。
我发现 Webpack 可以通过代码拆分来做到这一点,并通过一些配置将共享代码打包成自己的包。 但是,我无法真正控制每个包中的内容,除非我单独构建每个包然后只共享类型,使用我自己的模块作为外部库,这有点令人沮丧。
也许在这一点上,您可以说我已经做错了,我想听听我如何实现使用捆绑包作为普通 javascript 的目标(自己控制延迟/异步并使用自己的脚本标记作为好吧),而且我真的不想将所有内容打包为具有自己的配置、类型导出等的独立包。
希望你有整体背景。 更接近正题。
我有以下功能,它被捆绑到它自己的名为modal-manager.js
的块中。
public showModal (modal: ModalFilter|AbstractModal|number) {
let modalId: number;
console.log(modal);
console.log(typeof modal);
console.log(modal instanceof ModalFilter);
console.log(modal instanceof AbstractModal);
if (modal instanceof AbstractModal) {
modalId = modal.getId();
} else {
modalId = modal;
}
...
};
(最初它没有ModalFilter
因为ModalFilter
继承了AbstractModal
但我为了演示目的包含了它)
抽象模态会自动捆绑到modal-utils.js
因为它在模块之间共享。
接下来,我有另一个名为filter.js
大包。 这个字面上创建了 ModalFilter const modalFilter = new ModalFilter(...)
实例。 我认为这是提到向全局window
变量声明的 modalFilter 实例的工作。 问题是filter.js
调用modal.js
代码(通过window.modalFilter.showModal(modalFilter)
)没有任何问题,但我看到 console.log 的以下结果:
ModalFilter {shown: false, loading: false, closing: false, html: init(1), id: 0, …}
modal.bundle.23e2a2cb.js:264 object
modal.bundle.23e2a2cb.js:265 false
modal.bundle.23e2a2cb.js:266 false
我禁用了映射以获取更多代码并看到:
ModalManager.prototype.showModal = function (modal) {
var modalId;
console.log(modal);
console.log(typeof modal);
console.log(modal instanceof _builder_component_modal_filter__WEBPACK_IMPORTED_MODULE_1__[/* default */ "a"]);
console.log(modal instanceof _modal_abstract__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"]);
if (modal instanceof _modal_abstract__WEBPACK_IMPORTED_MODULE_0__[/* default */ "a"]) {
modalId = modal.getId();
}
else {
modalId = modal;
}
this.modals[modalId].show();
this.scrollLock(modalId);
};
根据我对 javascript 工作原理的理解,instanceof 应该检查对象创建器函数。 由于代码块是分开的( modal.js
与modal-utils.js
没有相同的代码),creator 函数应该是相同的。 然而,更多地了解细节,我发现webpackJsonp
可能非常棘手,并且从某种独立的环境中调用它们,但它仍然应该是调用FilterModal
和AbstractModal
的相同环境。 我相信ModalManager
可以有自己的环境。 但是调用的代码是 100% 相同的。 webpackJsonp
捆绑数组可能是问题的根源吗? 如果是这样,我怎样才能避免这种情况并使modal.js
包理解filter.js
和其他人都从modal-utils.js
引用相同的AbstractModal
?
如果我做错了,是否有一种简单的方法可以开始捆绑使用 TypeScript 和 Webpack(或其他工具)构建的小型高效脚本? 另外,我看到了 Webpack 的externals
功能,但还没有弄清楚如何在我的情况下使用它。 一般来说,除了instanceof
问题,我对当前设置没问题。 我想避免多次构建的原因是我可能会有几十个较小的包,它们在不同的模块之间共享,并且每个包都有几十个 npm 包似乎过多。
以此为序; 我不知道您在问题的instanceOf
部分面临的确切问题的答案。 这是针对“你是怎么做到的”部分的。
大约 4 周前,我们还使用大约 1-2 个.js
文件从.js
更改为.ts
实现。 显然,我们不想一次性将这些全部迁移到.ts
因为工作量太大。
我们最终做的是识别需要在特定页面上运行的.js
脚本,并将它们作为入口文件添加到 webpack 中。 然后对于所有其他支持脚本,如果我们需要在新的.ts
文件中包含它们的内容,我们实际上为它们创建了一个大的索引/桶文件,将它们导入,然后 webpack 会自动将它们包含在正确的范围中相应的.ts
文件。
这看起来像什么?
legacy.index.ts:对于我们想要在.ts
以任何方式引用的每个支持.js
文件。
var someFile_js = require("someFile.js");
export { someFile_js };
这允许我们在.ts
文件中导入和使用它:
import { someFile_js } from './legacy.index';
@tonix
。
要加载定义的列表:
配置文件
const SITE_INDEX = require('./path-to-js-file/list.js') module.exports = { entry: SITE_INDEX ... }
列表.js
{ "filename1": "./some-path/filename1.js" "filename2": "./some-path/filename2.ts" }
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.