Как вручную лениво загрузить модуль?

Я пытался загрузить модули без использования маршрутизатора SystemJsNgModuleLoader, но не смог заставить его работать:

this.loader.load(url).then(console.info);

я собираюсь Cannot find module xxx для любой строки, которую я использую для URL (aboslute/ относительные URL / пути... пробовал много вариантов). Я просмотрел исходный код маршрутизатора и не смог найти ничего, кроме этого SystemJsNgModuleLoader, Я даже не уверен, что должен использовать это...


Этот вопрос был задан только вчера в ng-europe 2016 конференция - Мишко и Матиас ответили:

Мишко Хевери: Нужно просто завладеть модулем, оттуда вы можете получить фабрику компонентов и динамически загрузить фабрику компонентов в любом месте приложения. Это именно то, что маршрутизатор делает внутри. Так что это довольно прямолинейно и для вас.

Matias Niemelä Единственное, что следует отметить, это то, что в модуле [Ng] есть нечто, называемое entryComponents и это идентифицирует компоненты, которые могут быть загружены лениво - это запись в этот набор компонентов. Поэтому, когда у вас есть модули, которые загружаются лениво, пожалуйста, поместите материал в entryComponents,

... но это не так уж далеко вперед без примеров и плохих документов по теме (;

Кто-нибудь знает, как загрузить модули вручную, не используя Route.loadChildren? Как заполучить модуль и что именно нужно делать entryComponents (Я читаю FAQ, но не могу попробовать без фактической загрузки модуля)?

2 ответа

Решение

Обновление Angular 6

Смотрите ответ@RomainLT

Предыдущие версии

Кто-нибудь знает, как загружать модули вручную, не используя Route.loadChildren?

Это может выглядеть так:

this.loader.load('./src/test.module#TestModule').then((factory: NgModuleFactory<any>) => {
  console.log(factory);
});

TestModule находится в файле ./src/test.module.ts (абсолютный путь)

Пример плунжера

Вот еще более сложный пример:

Если вы не загружаете компонент декларативно, как:

<my-comp></my-comp>

затем в вашем шаблоне, если вы хотите использовать этот компонент для динамической загрузки, вам нужно включить этот компонент в entryComponent одним из следующих способов:

Компилятор создает такие фабрики:

для каждой записикомпонент - host.factory.js

для каждого компонента component.ngfactory.js

Смотрите также

Пример для Angular-Cli

app.module.ts

providers: [
  SystemJsNgModuleLoader,
  provideRoutes([
     { loadChildren: 'app/lazy/lazy.module#LazyModule' }
  ])
],

app.component.ts

export class AppComponent implements  OnInit {
    title = 'Angular cli Example SystemJsNgModuleLoader.load';

    @ViewChild('container', { read: ViewContainerRef }) container: ViewContainerRef;

    constructor(private loader: SystemJsNgModuleLoader, private inj: Injector) {}

    ngOnInit() {
        this.loader.load('app/lazy/lazy.module#LazyModule').then((moduleFactory: NgModuleFactory<any>) => {
            const entryComponent = (<any>moduleFactory.moduleType).entry;
            const moduleRef = moduleFactory.create(this.inj);

            const compFactory = moduleRef.componentFactoryResolver.resolveComponentFactory(entryComponent);
            this.container.createComponent(compFactory);
        });
    }
}

Это также будет работать с AOT

Githug репо угловой-ленивый

Ленивая загрузка с Webpack и AOT

Компиляция с использованием ngc

Инициализация компилятора с использованием следующей фабрики

export function createJitCompiler () {
    return new JitCompilerFactory([{useDebug: false, useJit: true}]).createCompiler();
}

Github репо

[Угловой 6]

Привет,

Я поделюсь своим решением здесь, потому что я не нашел, как lazyload без маршрутизатора на stackru.

Путь Юрзуи работает, но он использует модуль Router для компиляции ленивого модуля, а я не хотел его использовать.

В нашем src/angular.json файл, который мы можем попросить @angular/cli собрать модуль отдельно.

Для этого мы добавим lazyModules введите "project" > "your-app-name" > "architect" > "build" > "options".

Как это:

  "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
  "version": 1,
  "newProjectRoot": "projects", 
  "projects": {
    "lazy-load-app": {
      "root": "",
      "sourceRoot": "src",
      "projectType": "application",
      "prefix": "app",
      "schematics": {},
      "architect": {
        "build": {
          "builder": "@angular-devkit/build-angular:browser",
          "options": {
            "outputPath": "dist/lazy-custom-element-app",
            "index": "src/index.html",
            "main": "src/main.ts",
            "polyfills": "src/polyfills.ts",
            "tsConfig": "src/tsconfig.app.json",
            "assets": [
              "src/favicon.ico",
              "src/assets"
            ],
            "styles": [
              "src/styles.css"
            ],
            "scripts": [],
            "lazyModules": [
              "src/app/lazy-load/lazy-load.module",
              "src/app/another-lazy-load/another-lazy-load.module"
            ]

тогда мы можем вызвать и загрузить наш скомпилированный модуль.

Как это:

export class LoaderComponent implements OnInit {

      // tag where we gonna inject the lazyload module and his default compononent "entry"
      @ViewChild('container', { read: ViewContainerRef }) viewRef: ViewContainerRef;

      constructor(
        private loader:     NgModuleFactoryLoader,
        private injector:   Injector,
        private moduleRef:  NgModuleRef<any>,) {
      }

      ngOnInit(): void {
       this.loader.load(this.pathModuleTemplate).then((moduleFactory: NgModuleFactory<any>) => {
          // our module had a static property 'entry' that references the component that  want to load by default with the module
          const entryComponent = (<any>moduleFactory.moduleType).entry;
          const moduleRef = moduleFactory.create(this.injector);
          const compFactory = moduleRef.componentFactoryResolver.resolveComponentFactory(entryComponent);
          this.viewRef.createComponent(compFactory);
        });
      }
}

источник: https://github.com/angular/angular-cli/blob/9107f3cc4e66b25721311b5c9272ec00c2dea46f/packages/angular_devkit/build_angular/src/server/schema.json

Надеюсь, это может помочь кому-то:)

Другие вопросы по тегам