尝试使用带有webpack的angular-cli延迟加载功能模块时出错

问题描述 投票:8回答:4

嗨,我正在尝试使用angular-cli与webpack(+生产力)来构建我的angular2应用程序但是我在尝试延迟加载模块时遇到问题,这些模块正在使用版本beta.10 ...

项目结构:

Project structure

的package.json

{
  "name": "my-app",
  "version": "0.0.0",
  "license": "MIT",
  "angular-cli": {},
  "scripts": {
    "start": "ng serve",
    "lint": "tslint \"src/**/*.ts\"",
    "test": "ng test",
    "pree2e": "webdriver-manager update",
    "e2e": "protractor"
  },
 "private": true,
 "dependencies": {
    "@angular/common": "2.0.0-rc.7",
    "@angular/compiler": "2.0.0-rc.7",
    "@angular/core": "2.0.0-rc.7",
    "@angular/forms": "^2.0.0-rc.7",
    "@angular/http": "2.0.0-rc.7",
    "@angular/platform-browser": "2.0.0-rc.7",
    "@angular/platform-browser-dynamic": "2.0.0-rc.7",
    "@angular/router": "3.0.0-rc.2",
    "angular2-cookie": "1.2.3",
    "core-js": "2.4.0",
    "material-design-icons": "2.2.3",
    "material-design-lite": "1.2.0",
    "reflect-metadata": "0.1.3",
    "rxjs": "5.0.0-beta.12",
    "ts-helpers": "^1.1.1",
    "zone.js": "0.6.21"
  },
  "devDependencies": {
    "@types/jasmine": "2.2.30",
    "@types/protractor": "1.5.16",
    "angular-cli": "^1.0.0-beta.11-webpack.9-4",
    "codelyzer": "0.0.26",
    "jasmine-core": "2.4.1",
    "jasmine-spec-reporter": "2.5.0",
    "karma": "0.13.22",
    "karma-chrome-launcher": "0.2.3",
    "karma-coverage": "1.0.0",
    "karma-jasmine": "0.3.8",
    "protractor": "3.3.0",
    "ts-node": "1.2.1",
    "tslint": "3.13.0",
    "typescript": "2.0.0"
  }
}

角cli.json

{
  "project": {
    "version": "1.0.0-beta.11-webpack",
    "name": "my-app"
  },
  "apps": [
    {
      "main": "main.ts",
      "test": "test.ts",
      "tsconfig": "tsconfig.json",
      "prefix": "app",
      "index": "index.html",
      "root": "src",
      "mobile": false,
      "scripts": [
        "polyfills.ts",
        "../node_modules/material-design-lite/material.min.js"
      ],
      "styles": [
        "../node_modules/material-design-icons/iconfont/material-icons.css",
        "../node_modules/material-design-lite/material.css"
      ],
      "assets": "assets",
      "environments": {
        "source": "environments/environment.ts",
        "dev": "environments/environment.ts",
        "prod": "environments/environment.prod.ts"
      }
    }
  ],
  "addons": [],
  "packages": [],
  "e2e": {
    "protractor": {
      "config": "config/protractor.conf.js"
    }
  },
  "test": {
    "karma": {
      "config": "config/karma.conf.js"
    }
  },
  "defaults": {
    "styleExt": "scss",
    "prefixInterfaces": false
  }
}

tsconfig.json

{
  "compilerOptions": {
    "declaration": false,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "lib": [
      "es6",
      "dom"
    ],
    "mapRoot": "./",
    "module": "es6",
    "moduleResolution": "node",
    "outDir": "../dist/out-tsc",
    "sourceMap": true,
    "target": "es5",
    "typeRoots": [
      "../node_modules/@types"
    ],
    "types": [
      "jasmine"
    ]
  }
}

app.routes.ts

import {Routes, RouterModule} from "@angular/router";
import {PageNotFoundComponent} from "./404.component";
import {AuthenticationGuard} from "./base/security";

const routes: Routes = [
  { path: '', redirectTo: 'home', pathMatch: 'full', canActivate: [AuthenticationGuard] },
  { path: 'home', loadChildren: 'app/modules/home/home.module#HomeModule' },
  { path: '**', component: PageNotFoundComponent }
];

export const routing = RouterModule.forRoot(routes, { useHash: true });

app.module.ts

import {NgModule} from "@angular/core";
import {BrowserModule} from "@angular/platform-browser";
import {routing} from "./app.routes";
import {AppComponent} from "./app.component";
import {PageNotFoundComponent} from "./404.component";
import {CoreModule} from "./core";

@NgModule({
  imports: [
    BrowserModule,
    routing,
    CoreModule
  ],
  declarations: [
    AppComponent,
    PageNotFoundComponent
  ],
  bootstrap: [AppComponent]
})
export class AppModule {}

模块/家用/ home.routes.ts

import {RouterModule} from '@angular/router';
import {HomeComponent} from './home.component';

import {AuthenticationGuard} from '../../base/security';

export const routing = RouterModule.forChild([
  { path: '', component: HomeComponent, canActivate: [AuthenticationGuard] }
]);

模块/家用/ home.module.ts

import {NgModule} from '@angular/core';
import {BaseModule} from '../../base/base.module';
import {routing} from './home.routes';
import {HomeComponent} from './home.component';
import {NavigationMenuComponent} from '../../base/components';

@NgModule({
    imports: [
    BaseModule,
    routing
  ],
  declarations: [
    HomeComponent,
    NavigationMenuComponent
  ],
  exports: [],
  providers: []
})
export class HomeModule {}

控制台错误消息:Console Error Message

有什么我忘了吗?我无法在任何地方找到任何关于如何继续这样做的文件...在此先感谢!

angular webpack lazy-loading angular-cli
4个回答
5
投票

这是一个装载机(angular2-router-loader)。但是,如果不破解配置,则无法在CLI中使用它。幸运的是,es6-promise-loader确实可以使用CLI开箱即用。

这对我有用:

首先我们需要es6-promise-loader:

npm i --save-dev es6-promise-loader

然后像这样定义你的路线:

{path:"lazy", loadChildren: () => require('es6-promise!./path/to/module')('ClassName')}

es6-promise-loader用以下代替上述内容:

loadChildren: () => new Promise(function (resolve) {
        require.ensure([], function (require) {
          resolve(require('./path/to/module')['ClassName']));
        });
      });

这是使用webpack加载模块的正确方法,但是放入每个路径都很麻烦。


2
投票

Angular-cli改变了beta.10和beta.14之间的构建系统,从SystemJS到Webpack。

我尝试使用延迟加载angular-cli(beta.17),它对我有用。

据我了解,

SystemJs - 我们需要为延迟加载提供完整路径Ex:./ app / dashboard / dashboard.module#DashboardModule

Webpack - 我们需要为延迟加载提供相对路径Ex:./ dashboard / dashboard.module#DashboardModule

注意:不要忘记重新启动服务器以查看反映的更改。(ng serve)

这个小观察解决了我的问题。请查看这是否有用或纠正我的任何事情。


1
投票

我有另一个解决方案:

在你的app.routers.ts上创建一个这样的函数:

let loadAoTModule = (path, module) => {

  let result = () => new Promise(function (resolve) {
    (require as any).ensure([], function (require: any) {
      resolve(require(path)[module]);
    });
  });

  return result;
}

const routes: Routes = [
  { path: '', redirectTo: 'customer', pathMatch: 'full'},

  { path          : 'customer'  ,
    // for a file locate on 'src/app/customer/customer.module'
    // and a module 'CustomerModule'
    loadChildren  :  loadAoTModule('./customer/customer.module', 'CustomerModule')

  }
];

对我来说很好。


0
投票

使用import动态加载模块。请记住在tsconfig文件中添加"module": "esNext",

loadChildren: () => import('projects/Reservation/src/app/app.module').then((m: any) => m.AppModule),

AppModule是模块的类名。

© www.soinside.com 2019 - 2024. All rights reserved.