我需要能够用一个非常简单的模块替换Angular应用程序中的一个相当大的模块,以使我的服务器端渲染构建工作负荷(避免所有不必要的需求,因为组件过于丰富而无法在服务器上正常工作)。如果没有替换,代码将尝试加载window
或document
。有些库我可以简单地用null-loader
替换,但是在这种情况下,我需要通过修剪此特定的Angular模块来切断整个依赖树。
尽管我进行了所有尝试来覆盖原始模块的尝试,但Angular(@ngtools/webpack
)仍以某种方式成功生成了我希望修剪的组件的require
调用...
我尝试过:
hostReplacementPaths
参数new AngularCompilerPlugin({
tsConfigPath: 'tsconfig.ssr.json',
entryModule: path.join(__dirname, 'src/js/landing/landing.server.module.ts#LandingServerModule'),
hostReplacementPaths: {
[path.resolve('./src/js/app/help.module.ts')]: path.resolve('./src/js/landing/server-mock.module.ts')
}
})
NormalModuleReplacementPlugin
new NormalModuleReplacementPlugin(
/help\.module\./,
resource => {
resource.requestresource.request.replace('app/help.module.ts', 'landing/server-mock.module.ts')
},
),
file-replace-loader
{
test: /help\.module\.ts/,
loader: 'file-replace-loader',
options: {
condition: 'if-replacement-exists',
replacement: path.resolve('./src/js/landing/server-mock.module.ts'),
async: true,
}
},
我怀疑Angular编译器正在扫描文件以查找webpack之外的依赖关系...
关于在构建时如何用模拟模块覆盖单个Angular模块的任何想法?
我找到了解决方案。我必须创建一个中间模块src/js/app/mock-intermediate-version-of-the-module.ts
,以重新导出需要修剪的模块
import { NgModule } from '@angular/core';
import { ModuleThatYouNeedToReplaceAtBuildTime } from '../app/module-to-replace-at-build-time';
@NgModule({
exports: [
ModuleThatYouNeedToReplaceAtBuildTime,
],
})
export class IntermediateVersionOfTheModule {
}
并创建IntermediateVersionOfTheModule
的模拟版本:
src/js/app/mock-intermediate-version-of-the-module.ts
import { NgModule } from '@angular/core';
@NgModule({
})
export class LandingHelpModule {
}
然后在AngularCompilerPlugin
配置中传递以下内容:
new AotPlugin({
tsConfigPath: 'tsconfig.ssr.json',
entryModule: path.join(__dirname, 'src/js/landing/landing.server.module.ts#LandingServerModule'),
hostReplacementPaths: {
[path.resolve('intermediate-version-of-the-module.ts')]: path.resolve('./mock-intermediate-version-of-the-module.ts')
}
})
诀窍是替换只是一个中间模块,然后重新导出我们要修剪的实际模块。有角度的编译器扫描了我们的整个模块树,没有模块的组件和具有相同组件的重复模块都无法处理任何组件。
希望对大家有用!