|
8 | 8 |
|
9 | 9 | import type { Metafile } from 'esbuild';
|
10 | 10 | import { extname } from 'node:path';
|
| 11 | +import { type Context, createContext, runInContext } from 'node:vm'; |
11 | 12 | import { NormalizedApplicationBuildOptions } from '../../builders/application/options';
|
12 | 13 | import { type BuildOutputFile, BuildOutputFileType } from '../../tools/esbuild/bundler-context';
|
13 | 14 | import { createOutputFile } from '../../tools/esbuild/utils';
|
@@ -139,20 +140,30 @@ export function generateAngularServerAppManifest(
|
139 | 140 | } {
|
140 | 141 | const serverAssetsChunks: BuildOutputFile[] = [];
|
141 | 142 | const serverAssets: Record<string, string> = {};
|
| 143 | + let ctx: Context | undefined; |
| 144 | + |
142 | 145 | for (const file of [...additionalHtmlOutputFiles.values(), ...outputFiles]) {
|
143 | 146 | const extension = extname(file.path);
|
144 | 147 | if (extension === '.html' || (inlineCriticalCss && extension === '.css')) {
|
145 | 148 | const jsChunkFilePath = `assets-chunks/${file.path.replace(/[./]/g, '_')}.mjs`;
|
| 149 | + const escapedContent = escapeUnsafeChars(file.text); |
| 150 | + |
146 | 151 | serverAssetsChunks.push(
|
147 | 152 | createOutputFile(
|
148 | 153 | jsChunkFilePath,
|
149 |
| - `export default \`${escapeUnsafeChars(file.text)}\`;`, |
| 154 | + `export default \`${escapedContent}\`;`, |
150 | 155 | BuildOutputFileType.ServerApplication,
|
151 | 156 | ),
|
152 | 157 | );
|
153 | 158 |
|
| 159 | + // This is needed because JavaScript engines script parser convert `\r\n` to `\n` in template literals, |
| 160 | + // which can result in an incorrect byte length. |
| 161 | + ctx ??= createContext({ textEncoder: new TextEncoder(), size: 0 }); |
| 162 | + ctx.size = 0; |
| 163 | + runInContext(`size = textEncoder.encode(\`${escapedContent}\`).byteLength`, ctx); |
| 164 | + |
154 | 165 | serverAssets[file.path] =
|
155 |
| - `{size: ${file.size}, hash: '${file.hash}', text: () => import('./${jsChunkFilePath}').then(m => m.default)}`; |
| 166 | + `{size: ${ctx.size}, hash: '${file.hash}', text: () => import('./${jsChunkFilePath}').then(m => m.default)}`; |
156 | 167 | }
|
157 | 168 | }
|
158 | 169 |
|
|
0 commit comments