Angular 12升级后SSR构建时Webpack挂起并报错
Angular 12升级后Webpack SSR构建卡壳并报错
背景
使用Webpack v5.50为Angular项目执行服务端渲染(SSR)构建,原Webpack配置如下:
module.exports = { mode: 'none', entry: { server: './server.ts', }, externals: { './dist/server/main': 'require("./server/main")' }, target: 'node', resolve: { extensions: ['.ts', '.js'] }, optimization: { minimize: false }, output: { // 将输出文件放在dist根目录 path: path.join(__dirname, 'dist'), library: 'app', libraryTarget: 'umd', filename: '[name].js', }, module: { noParse: /polyfills-.*\.js/, rules: [ { test: /\.ts$/, loader: 'ts-loader' }, { // 将@angular/core内部文件标记为使用SystemJS风格动态导入 // 移除该规则会触发弃用警告 test: /(\\|\/)@angular(\\|\/)core(\\|\/).+\.js$/, parser: { system: true }, }, ] }, plugins: [ new webpack.ContextReplacementPlugin( // 修复"Critical dependency: the request of a dependency is an expression"警告 /(.+)?angular(\\|\/)core(.+)?/, path.join(__dirname, 'src'), // 项目src目录路径 {} ), new webpack.ContextReplacementPlugin( /(.+)?express(\\|\/)(.+)?/, path.join(__dirname, 'src'), {} ) ] }
升级至Angular 12后,相同构建会在emit阶段挂起数小时无进展,最终报错:
[webpack.Progress] 95% emitting emit [webpack.Progress] 95% emitting emit [webpack.Progress] 98% emitting after emit [webpack.Progress] 98% emitting after emit [webpack.Progress] 99% done plugins [webpack.Progress] 99% done plugin [webpack.Progress] 99% cache store build dependencies [webpack.Progress] 99% cache store build dependencies [webpack.Progress] 99% cache begin idle [webpack.Progress] 99% cache begin idle [webpack.Progress] 100% [webpack.Progress] 100% /node_modules/webpack/lib/stats/DefaultStatsPrinterPlugin.js:1183 return match.replace(content, format(content)); ^ RangeError: Invalid string length at String.replace (<anonymous>) /node_modules/webpack/lib/stats/DefaultStatsPrinterPlugin.js:1183:18 at String.replace (<anonymous>)
环境信息
- Node: 16.19.1
- Webpack: 5.50
- Typescript: 4.3.5
- @angular-devkit/build-angular: ~12.2.18(内部依赖Webpack 5.50用于SSR编译)
解决方案
1. 限制Webpack Stats输出规模
报错源于构建生成的Stats数据过大,超出字符串处理上限,在Webpack配置中添加stats选项精简输出:
module.exports = { // ...其他原有配置 stats: { all: false, errors: true, warnings: true, timings: true, builtAt: true } }
2. 移除过时的ContextReplacementPlugin配置
Angular 12已内置处理依赖表达式的逻辑,无需手动配置ContextReplacementPlugin,直接删除配置中的两个该插件实例即可。
3. 优化Externals配置
适配Angular 12的SSR打包结构,改用函数形式配置externals,避免硬编码路径导致的无效依赖:
externals: [ (context, request, callback) => { const isExternal = request.startsWith('@angular/') || request.startsWith('rxjs/') || request.startsWith('express/'); if (isExternal) { return callback(null, `commonjs ${request}`); } callback(); } ]
4. 替换ts-loader为官方Angular Webpack加载器
Angular 12推荐使用@ngtools/webpack替代ts-loader处理Angular文件,修改module.rules中的对应规则:
module: { // ...其他配置 rules: [ { test: /\.ts$/, loader: '@ngtools/webpack', exclude: [/\.(spec|e2e)\.ts$/] }, // ...其他原有规则 ] }
5. 升级Angular构建工具补丁包(可选)
升级同大版本的@angular-devkit/build-angular到最新补丁版,修复已知的SSR构建问题:
npm install @angular-devkit/build-angular@~12.2.19 --save-dev
内容的提问来源于stack exchange,提问作者HARI PRASAD
相关产品推荐
相关产品推荐

