Webpack代码拆分在块之间中断instanceof



tl:dr;

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+Webpack4.41.6,这个项目大部分都是旧的代码库。基本上,我想将几个小模块打包到捆绑包中,以便在不将整个项目移动到新的js堆栈上的情况下进行软迁移。

我发现Webpack可以通过代码拆分来实现这一点,并通过一些配置将共享代码打包成自己的捆绑包。然而,我无法真正控制每个捆绑包中的内容,除非我单独构建每个捆绑包,然后只共享类型,使用我自己的模块作为外部库,这有点令人沮丧。

也许在这一点上,你可以说我已经做错了什么,我想听听我如何才能实现像使用普通javascript一样使用捆绑包的目标(我自己控制defer/async,也自己使用script标记(,我真的不想把所有东西都打包成一个独立的包,有自己的配置、类型导出等等。

希望你了解整体情况。更接近要点。

我有以下函数,它被绑定到它自己的块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的大捆绑包。这一个实际上创建了ModalFilterconst 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.jsmodal-utils.js没有相同的代码(,创建者函数应该是相同的。然而,更详细地说,我看到webpackJsonp可能非常棘手,并且从某种独立的环境中调用它们,但它仍然应该是调用FilterModalAbstractModal的相同环境。我相信ModalManager可能有自己的环境。但调用的代码是100%相同的。webpackJsonp捆绑数组会是问题的根源吗?如果是这样,我如何避免这种情况,并使modal.js捆绑包理解filter.js和其他捆绑包都引用了modal-utils.js中的相同AbstractModal

如果我做错了,有没有一种简单的方法可以开始捆绑使用TypeScript和Webpack(或其他工具(构建的小型高效脚本?此外,我看到了Webpack的externals功能,但还没有弄清楚如何在我的情况下使用它。总的来说,除了instanceof问题外,我对当前的设置还可以。我想避免多个构建的原因是,我可能会有几十个较小的捆绑包在不同的模块之间共享,而每个模块都有十几个npm包似乎太多了。

用;关于你问题的instanceOf部分,我不知道你面临的确切问题的答案。这是针对"你是怎么做到的"部分。


大约。4周前,我们还将.js实现更改为.ts实现,其中包含大约1-2个hunderd.js文件。显然,我们不想一次将这些迁移到.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。加载定义的列表:

webpack.config

const SITE_INDEX = require('./path-to-js-file/list.js')
module.exports = {
entry: SITE_INDEX
...
}

list.js

{
"filename1": "./some-path/filename1.js"
"filename2": "./some-path/filename2.ts"
}

最新更新