angular – 如何仅在需要时加载Zone.js

前端之家收集整理的这篇文章主要介绍了angular – 如何仅在需要时加载Zone.js前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在创建一个可以动态注入正在运行的网站的Angular 2应用程序.这个应用程序的重点是能够直观地修改网站内容.

当有问题的网站也没有使用Angular 2运行时,一切都按预期工作.特别是,当原始网站使用Angular 2和Zone.js时,我的应用程序也尝试加载Zone.js但它在error: Zone already loaded崩溃.我是使用Webpack作为构建系统,我尝试通过将构建分为3个部分来解决问题:清单,polyfill和app. Manifest只包含Webpack清单,polyfill包含core-js和zone.js,其余部分在app中.还有第四个名为index的块.这是放入网站的那个,它首先检查是否定义了window.Zone.如果是,则仅添加清单和应用程序.否则也是polyfill.

问题是,当未加载polyfill chunk时,Webpack中缺少该块中的所有模块.因此,当代码从需要core-js或Zone.js的应用程序块中获得一些导入时(我认为这正在发生),我收到此错误

  1. TypeError: Cannot read property 'call' of undefined
  2. at __webpack_require__ (manifest.js:55)
  3. at Object.<anonymous> (app.js:15016)
  4. at __webpack_require__ (manifest.js:55)
  5. at Object.<anonymous> (app.js:65567)
  6. at __webpack_require__ (manifest.js:55)
  7. at Object.<anonymous> (app.js:65163)
  8. at __webpack_require__ (manifest.js:55)
  9. at Object.defineProperty.value (app.js:65137)
  10. at __webpack_require__ (manifest.js:55)
  11. at webpackJsonpCallback (manifest.js:26)

清单文件中的某个地方:

  1. /******/ // Execute the module function
  2. /******/ modules[moduleId].call(module.exports,module,module.exports,__webpack_require__);

如何将Webpack或Angular配置为不将zone.js作为依赖项导入,而是使用已在窗口中注册的那个?我希望能够有条件地加载core-js和zone.js,只要它尚未加载到网站上.

UPDATE

修改了我的构建(Webpack)只使用一个bundle.在那个包中,我尝试使用Webpack的dynamic imports,如下所示:

  1. // import reflect Metadata shim
  2. import 'core-js/es6/reflect';
  3. import 'core-js/es7/reflect';
  4.  
  5.  
  6. // Angular and application imports
  7. import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
  8. import { AppModule } from './app.module';
  9. import { ViewEncapsulation } from '@angular/core';
  10.  
  11.  
  12. // load the editor in the next frame
  13. requestAnimationFrame(() => {
  14.  
  15. if (window.Zone) {
  16. bootstrap();
  17. }
  18. else {
  19. import('zone.js/dist/zone') // <-- PROBLEM HERE
  20. .then(bootstrap);
  21. }
  22.  
  23. });
  24.  
  25.  
  26. // bootstraps the editor
  27. function bootstrap() {
  28.  
  29. // add the root component to the DOM
  30. const root = document.createElement('efe-root');
  31. document.body.appendChild(root);
  32.  
  33. // bootstrap the Angular app
  34. platformBrowserDynamic()
  35. .bootstrapModule(AppModule,{
  36. defaultEncapsulation: ViewEncapsulation.Native
  37. })
  38. .then(() => console.debug('Exponea Free Editor has bootstrapped'));
  39.  
  40. }

我正在使用Typescript,这需要定义文件.问题是Zone.js is an ambient dependency所以当我像这样使用它时,我得到一个关于缺少定义文件错误.我该如何解决这个问题?

如果您不想将zone.js加载到捆绑包中,只需从polyfills.ts中删除导入:
  1. import 'core-js/es6/reflect';
  2. import 'core-js/es7/reflect';
  3. import 'zone.js/dist/zone'; <---- remove this line

如果要在运行时检查Zone.js的存在并根据结果确定,请使用以下命令:

  1. declare var System;
  2. if (!window['Zone']) {
  3. System.import('zone.js/dist/zone'); // Included with Angular CLI.
  4. }

猜你在找的Angularjs相关文章