lig*_*lbs 17 javascript typescript webpack angular angular-router
我们希望将我们的大型前端项目划分为多个单独部署的项目,这些项目更易于使用.我试图包含一个捆绑的ngModule来处理来自另一个应用程序的路由.应用程序必须不知道彼此的配置.捆绑包将通过全局变量共享一些大的依赖项(如Angular).我们不需要动摇捆绑包,我们可能只需要接受一些重复的依赖项.
根路由器抱怨说
Error: No NgModule metadata found for 'TestsetModule'.
Run Code Online (Sandbox Code Playgroud)
这让我相信子模块在加载时没有进行角度编译,或者由于某种原因没有注册其模块.我认为可能需要手动编译模块,但我不知道如何使用这个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);
Run Code Online (Sandbox Code Playgroud)
我也尝试使用角度路由器的字符串解析语法,而不是你看到的这个奇怪的全局事物,但我有类似的问题.
这是正在加载的模块,除了全局导出之外非常标准:
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};
Run Code Online (Sandbox Code Playgroud)
这是根包的webpack配置.通过命名不佳的"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;
};
Run Code Online (Sandbox Code Playgroud)
这是子包的webpack配置.注意"外部",它将角度视为全局.
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;
};
Run Code Online (Sandbox Code Playgroud)
为了更好地衡量,这里是我的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
}
}
Run Code Online (Sandbox Code Playgroud)
如果你还在读书,真棒.当两个bundle都是同一个webpack配置的一部分并且子模块只是一个块时,我能够使这个工作.Angular旨在实现这一目标.但我们的用例是让孩子和父母在运行之前彼此无知.
正如你所提到的
应用程序必须不了解彼此的配置。
我在 Angular2 中也遇到了类似的问题。我通过创建一个子应用程序解决了这个问题。一个单独的子 main.browser.ts 和 index.html 文件。它有自己的依赖项,共享相同的节点模块。两个主要模块引导不同的应用程序组件。我们在没有 angular-cli 的情况下开发 Angular。
在 webpack 配置中,我添加了
entry: {
'polyfills': './src/polyfills.browser.ts',
'main' . : './src/main.browser.aot.ts',
'sub-main' : '/src/sub-main.browser.ts'
},
Run Code Online (Sandbox Code Playgroud)
以及更详细的 HtmlWebpackPlugin。在块中,我们仅加载将在两个应用程序中使用的模块。如果我们看到 Polyfill 很常见。
new HtmlWebpackPlugin({
template: 'src/index.html',
title: METADATA.title,
chunksSortMode: 'dependency',
metadata: METADATA,
inject: 'head',
chunks: ['polyfills','main']
}),
new HtmlWebpackPlugin({
template: 'src/index2.html',
title: 'Sub app',
chunksSortMode: 'dependency',
metadata: METADATA,
inject: 'head',
filename: './sub-app.html',
chunks: ['polyfills','sub-main']
}),
Run Code Online (Sandbox Code Playgroud)
下一个任务是为开发环境的两个子应用程序创建单独的端点。
devServer: {
port: METADATA.port,
host: METADATA.host,
historyApiFallback: true,
watchOptions: {
aggregateTimeout: 300,
poll: 1000
},
proxy: {
"/sub-app": {
target: "http://localhost:3009",
bypass: function(req, res, proxyOptions) {
return "/index2.html";
}
}
}
},
Run Code Online (Sandbox Code Playgroud)
现在,当我构建项目时,会生成两个不同的 HTML 文件。每个都有自己的 javascript 捆绑依赖项和公共资产。它们也可以部署在不同的服务器上。
我通过大量的试验和错误完成了我的 POC。我的建议是看起来比 Angular 更进一步。查看 webpack 如何部署您当前的项目。如果您可以配置它来满足您的目的。
| 归档时间: |
|
| 查看次数: |
1164 次 |
| 最近记录: |