Philipp Schrader | 175a93c | 2023-02-19 13:13:40 -0800 | [diff] [blame] | 1 | /** |
| 2 | * ESBuild plugin to run the angular linker via babel plugin while bundling. |
| 3 | * |
| 4 | * Inspired by: |
| 5 | * |
| 6 | * Internal angular/dev-infra-private-builds esbuild plugin |
| 7 | * - https://github.com/angular/dev-infra-private-builds/blob/afcc2494c45a63660cb560ee96179969610435db/shared-scripts/angular-linker/esbuild-plugin.mjs |
| 8 | * Rollup |
| 9 | * - https://github.com/angular/angular/blob/14.0.5/integration/ng_elements/rollup.config.mjs |
| 10 | * Webpack |
| 11 | * - https://github.com/angular/angular-cli/blob/14.0.5/packages/angular_devkit/build_angular/src/babel/webpack-loader.ts#L97-L114 |
| 12 | */ |
| 13 | |
| 14 | import { transformFileAsync } from '@babel/core'; |
| 15 | import { |
| 16 | ConsoleLogger, |
| 17 | NodeJSFileSystem, |
| 18 | LogLevel, |
| 19 | } from '@angular/compiler-cli'; |
| 20 | import { createEs2015LinkerPlugin } from '@angular/compiler-cli/linker/babel'; |
| 21 | |
| 22 | const linkerBabelPlugin = createEs2015LinkerPlugin({ |
| 23 | fileSystem: new NodeJSFileSystem(), |
| 24 | logger: new ConsoleLogger(LogLevel.warn), |
| 25 | unknownDeclarationVersionHandling: 'error', |
| 26 | // Must enable JIT for unit tests |
| 27 | // TODO: would be ideal to only set this for tests |
| 28 | linkerJitMode: true, |
| 29 | // Workaround for https://github.com/angular/angular/issues/42769 and https://github.com/angular/angular-cli/issues/22647. |
| 30 | sourceMapping: false, |
| 31 | }); |
| 32 | |
| 33 | const ngLinkerPlugin = { |
| 34 | name: 'ng-linker-esbuild', |
| 35 | setup(build: any) { |
| 36 | build.onLoad({ filter: /node_modules/ }, async (args: any) => { |
| 37 | const filePath = args.path; |
| 38 | const transformResult = await transformFileAsync(filePath, { |
| 39 | filename: filePath, |
| 40 | filenameRelative: filePath, |
| 41 | plugins: [linkerBabelPlugin], |
| 42 | sourceMaps: 'inline', |
| 43 | compact: false, |
| 44 | }); |
| 45 | |
| 46 | if (!transformResult) { |
| 47 | throw new Error('Babel NG Linker error'); |
| 48 | } |
| 49 | |
| 50 | return { contents: transformResult.code }; |
| 51 | }); |
| 52 | }, |
| 53 | }; |
| 54 | |
| 55 | export default { |
| 56 | // Ensure only [m]js is consumed. Any typescript should be precompiled |
| 57 | // and not consumed by esbuild. |
| 58 | resolveExtensions: ['.mjs', '.js'], |
| 59 | plugins: [ngLinkerPlugin], |
| 60 | }; |