Мы хотим разделить наши крупные проекты с интерфейсом на несколько отдельно развернутых проектов, с которыми легче работать. Я пытаюсь включить связанный ngModule для обработки маршрута из другого приложения. Приложения должны не знать друг друга. Пакеты будут делиться некоторыми большими зависимостями (например, Angular) через глобальные переменные. Нам не нужно встряхивать пучки, и нам просто нужно принять некоторые дублирующие зависимости.
Корневой маршрутизатор жалуется, что
Error: No NgModule metadata found for 'TestsetModule'.
что заставляет меня думать, что дочерний модуль не является angular, скомпилированным при загрузке, или по какой-либо причине не регистрирует его модуль. Я думаю, что может понадобиться вручную скомпилировать модуль, но я не уверен, как использовать этот https://angular.io/api/core/Compiler#compileModuleAndAllComponentsAsync
Корневое приложение загружает ребенка по маршруту:
import { ModuleWithProviders } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
const load = require("little-loader");
const routes: Routes = [
{ path: ``, loadChildren: () => new Promise(function (resolve) {
load('http://localhost:3100/testset-module-bundle.js',(err: any) => {
console.log('global loaded bundle is: ', (<any>global).TestsetModule )
resolve((<any>global).TestsetModule)
}
)
})}
];
export const HostRouting: ModuleWithProviders = RouterModule.forRoot(routes);
Я также попытался использовать синтаксис синтаксиса строкового синтаксиса angular, а не эту странную глобальную вещь, которую вы видите, но у меня были подобные проблемы.
Вот загружаемый модуль, очень стандартный, за исключением глобального экспорта:
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { HttpModule } from '@angular/http';
//import { MaterialModule } from '@angular/material';
import { FlexLayoutModule } from '@angular/flex-layout';
import { FormsModule } from '@angular/forms';
import { LoggerModule, Level } from '@churro/ngx-log';
import { FeatureLoggerConfig } from './features/logger/services/feature-logger-config';
import { TestsetComponent } from './features/testset/testset.component';
import { TestsetRouting } from './testset.routing';
@NgModule({
imports: [
CommonModule,
//MaterialModule,
FlexLayoutModule,
HttpModule,
FormsModule,
LoggerModule.forChild({
moduleName: 'Testset',
minLevel: Level.INFO
}),
TestsetRouting,
],
declarations: [TestsetComponent],
providers: [
/* TODO: Providers go here */
]
})
class TestsetModule { }
(<any>global).TestsetModule = TestsetModule
export {TestsetModule as default, TestsetModule};
Вот конфигурация веб-пакета корневого пакета. Обратите внимание на глобальный экспорт через слабо названный "ProvidePlugin".
const webpack = require('webpack');
const AotPlugin = require('@ngtools/webpack').AotPlugin;
const path = require('path');
const BrowserSyncPlugin = require('browser-sync-webpack-plugin');
const IgnorePlugin = require('webpack/lib/IgnorePlugin');
const PolyfillsPlugin = require('webpack-polyfills-plugin');
const WebpackSystemRegister = require('webpack-system-register');
module.exports = (envOptions) => {
envOptions = envOptions || {};
const config = {
entry: {
'bundle': './root.ts'
},
output: {
libraryTarget: 'umd',
filename: '[name].js',//"bundle.[hash].js",
chunkFilename: '[name]-chunk.js',
path: __dirname
},
externals: {
},
resolve: {
extensions: ['.ts', '.js', '.html'],
},
module: {
rules: [
{ test: /\.html$/, loader: 'raw-loader' },
{ test: /\.css$/, loader: 'raw-loader' },
]
},
devtool: '#source-map',
plugins: [
new webpack.ProvidePlugin({
'angular': '@angular/core',
'ngrouter': '@angular/router',
'ngxlog':'@churro/ngx-log'
})
]
};
config.module.rules.push(
{ test: /\.ts$/, loaders: [
'awesome-typescript-loader',
'angular-router-loader',
'angular2-template-loader',
'source-map-loader'
] }
);
}
return config;
};
И вот конфигурация веб-пакета дочернего пакета. Обратите внимание на "внешние", которые ищут angular как глобальный.
module.exports = (envOptions) => {
envOptions = envOptions || {};
const config = {
entry: {
'testset-module-bundle': './src/index.ts'
},
output: {
//library: 'TestsetModule',
libraryTarget: 'umd',
filename: '[name].js',//"bundle.[hash].js",
chunkFilename: '[name]-chunk.js',
path: path.resolve(__dirname, "dist")
},
externals: {
//expect these to come from the app that imported us
// name to be required : name from global
'angular': '@angular/core',
'ngrouter': '@angular/router',
'ngxlog': '@churro/ngx-log'
},
resolve: {
extensions: ['.ts', '.js', '.html'],
},
module: {
rules: [
{ test: /\.html$/, loader: 'raw-loader' },
{ test: /\.css$/, loader: 'raw-loader' },
]
},
devtool: '#source-map',
plugins: [
]
};
config.module.rules.push(
{ test: /\.ts$/, loaders: [
'awesome-typescript-loader',
'angular-router-loader',
'angular2-template-loader',
'source-map-loader'
] }
);
}
return config;
};
И для хорошей меры здесь находится мой файл tsconfig, который читает "awesome- typescript -loader".
{
"compilerOptions": {
"target": "es5",
"module": "es2015",
"moduleResolution": "node",
"sourceMap": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"removeComments": false,
"noImplicitAny": true,
"suppressImplicitAnyIndexErrors": true,
"baseUrl": ".",
"rootDir": "src",
"outDir": "app",
"paths": {
"@capone/*": [
"*"
],
"@angular/*": [
"node_modules/@angular/*"
],
"rxjs/*": [
"node_modules/rxjs/*"
]
}
},
"exclude": ["node_modules", "src/node_modules", "compiled", "src/dev_wrapper_app"],
"angularCompilerOptions": {
"genDir": "./compiled",
"skipMetadataEmit": true
}
}
Если вы все еще читаете, потрясающе. Я смог получить эту работу, когда оба пакета являются частью одной и той же конфигурации webpack, а дочерний модуль - всего лишь кусок. angular предназначен для этого. Но наш случай использования заключается в том, чтобы дети и родители не знали друг друга до времени исполнения.