我正在创建一个可以动态注入正在运行的网站的 Angular 2 应用程序。这个应用程序的重点是能够直观地修改网站内容。
当有问题的网站也没有使用 Angular 2 运行时,一切都按预期工作。特别是,当原始网站使用 Angular 2 和 Zone.js 时,我的应用程序也尝试加载 Zone.js,但它在error: Zone already loaded
. 我使用 Webpack 作为构建系统,我试图通过将构建分成 3 个部分来解决这个问题:manifest
、polyfill
和app
. Manifest 只包含 Webpack 清单,polyfill 包含core-js
and zone.js
,其余的在app
. 还有第四个块叫做index
. 这是放置在网站中的内容,它首先检查是否window.Zone
已定义。如果是,则仅添加manifest
和app
。否则也polyfill
。
问题是当polyfill
块没有加载时,该块中的所有模块都从 Webpack 中丢失。因此,当代码从需要或(我认为正在发生的事情)import
的块中到达一些时,我会收到此错误:app
core-js
Zone.js
TypeError: Cannot read property 'call' of undefined
at __webpack_require__ (manifest.js:55)
at Object.<anonymous> (app.js:15016)
at __webpack_require__ (manifest.js:55)
at Object.<anonymous> (app.js:65567)
at __webpack_require__ (manifest.js:55)
at Object.<anonymous> (app.js:65163)
at __webpack_require__ (manifest.js:55)
at Object.defineProperty.value (app.js:65137)
at __webpack_require__ (manifest.js:55)
at webpackJsonpCallback (manifest.js:26)
清单文件中的某处:
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
问题
如何将 Webpack 或 Angular 配置为不zone.js
作为依赖项导入,而是使用已在窗口上注册的依赖项?我希望能够有条件地加载core-js
,并且zone.js
仅当它尚未加载到网站上时。
更新
我修改了我的构建(Webpack),只使用一个包。在那个包中,我尝试使用 Webpack 的动态导入,如下所示:
// import reflect metadata shim
import 'core-js/es6/reflect';
import 'core-js/es7/reflect';
// Angular and application imports
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app.module';
import { ViewEncapsulation } from '@angular/core';
// load the editor in the next frame
requestAnimationFrame(() => {
if (window.Zone) {
bootstrap();
}
else {
import('zone.js/dist/zone') // <-- PROBLEM HERE
.then(bootstrap);
}
});
// bootstraps the editor
function bootstrap() {
// add the root component to the DOM
const root = document.createElement('efe-root');
document.body.appendChild(root);
// bootstrap the Angular app
platformBrowserDynamic()
.bootstrapModule(AppModule, {
defaultEncapsulation: ViewEncapsulation.Native
})
.then(() => console.debug('Exponea Free Editor has bootstrapped'));
}
我正在使用 Typescript,这需要定义文件。问题是这Zone.js
是一个环境依赖,所以当我像这样使用它时,我收到一个关于缺少定义文件的错误。我该如何解决这个问题?