-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
f7725ef
commit 91fce76
Showing
7 changed files
with
145 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
{ | ||
"executors": { | ||
"bundle": { | ||
"implementation": "./src/executors/bundle/executor", | ||
"schema": "./src/executors/bundle/schema.json", | ||
"description": "Angular Post Processing Rollup Bundler", | ||
"hasher": "./src/executors/bundle/hasher" | ||
} | ||
} | ||
} |
11 changes: 11 additions & 0 deletions
11
packages/angular-rollup/src/executors/bundle/executor.spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
import { BundleExecutorSchema } from './schema'; | ||
import executor from './executor'; | ||
|
||
const options: BundleExecutorSchema = {}; | ||
|
||
describe('Bundle Executor', () => { | ||
it('can run', async () => { | ||
const output = await executor(options); | ||
expect(output.success).toBe(true); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
import { readFileSync, rmSync, readdirSync, renameSync } from 'node:fs'; | ||
import { join } from 'node:path'; | ||
|
||
import { Metafile } from 'esbuild'; | ||
import { ManualChunksOption, OutputOptions, PreRenderedChunk, rollup } from 'rollup'; | ||
|
||
import { BundleExecutorSchema } from './schema'; | ||
|
||
const POLYFILLS_ENTRY_POINT = 'angular:polyfills:angular:polyfills'; | ||
const statsJsonPath = (outputPath: string) => join(outputPath,'stats.json'); | ||
const entryChunkPath = (outputPath: string, chunkName: string) => join(outputPath, chunkName); | ||
const noEntryChunkError = () => new Error('No entry chunk found matching @TODO improve error message'); | ||
const chunkWithEntryPoint = (entryPoint: string, outputChunks: Metafile['outputs']): string | undefined => { | ||
return Object.keys(outputChunks).find(output => outputChunks[output].entryPoint === entryPoint); | ||
}; | ||
const entryChunk = (entryPoint: string, statsJson: Metafile): string => { | ||
const chunkName = chunkWithEntryPoint(entryPoint, statsJson.outputs); | ||
if (!chunkName) throw noEntryChunkError(); | ||
return chunkName; | ||
} | ||
|
||
function getJson<T = any>(path: string) { | ||
return JSON.parse(readFileSync(join(path), {encoding: 'utf-8'})) as T; | ||
} | ||
|
||
export default async function runExecutor(options: BundleExecutorSchema) { | ||
console.log('Executor ran for Bundle', options); | ||
|
||
const statsJson = getJson<Metafile>(statsJsonPath(options.outputPath)); | ||
const mainChunk = entryChunk(options.main, statsJson); | ||
const polyfillsChunk = entryChunk(POLYFILLS_ENTRY_POINT, statsJson); | ||
const input = [entryChunkPath(options.outputPath, mainChunk), entryChunkPath(options.outputPath, polyfillsChunk)]; | ||
|
||
const dir = join('tmp', options.outputPath); | ||
|
||
const manualChunks: ManualChunksOption = (id, meta) => { | ||
if (id.includes(mainChunk) || id.includes(polyfillsChunk)) return; | ||
if (id.includes("chunk")) return "extra"; | ||
return 'vendor'; | ||
}; | ||
|
||
const chunkFileNames = (chunkInfo: PreRenderedChunk): string => { | ||
return `${chunkInfo.type}-${chunkInfo.name}.js`; | ||
} | ||
const output: OutputOptions = { | ||
manualChunks, | ||
chunkFileNames, | ||
dir | ||
}; | ||
const b = await rollup({ input }); | ||
await b.write(output); | ||
|
||
for (const output of Object.keys(statsJson.outputs)) { | ||
if (!output.endsWith('.css')) rmSync(join(options.outputPath, output)); | ||
} | ||
|
||
for (const output of readdirSync(dir)) { | ||
renameSync(join(dir, output), join(options.outputPath, output)); | ||
} | ||
|
||
rmSync(dir, {recursive: true}); | ||
|
||
return { success: true }; | ||
} |
26 changes: 26 additions & 0 deletions
26
packages/angular-rollup/src/executors/bundle/hasher.spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
import { TaskHasher, HasherContext } from '@nx/devkit'; | ||
|
||
import { bundleHasher } from './hasher'; | ||
|
||
describe('bundleHasher', () => { | ||
it('should generate hash', async () => { | ||
const mockHasher: TaskHasher = { | ||
hashTask: jest.fn().mockReturnValue({ value: 'hashed-task' }), | ||
} as unknown as TaskHasher; | ||
const hash = await bundleHasher( | ||
{ | ||
id: 'my-task-id', | ||
target: { | ||
project: 'proj', | ||
target: 'target', | ||
}, | ||
overrides: {}, | ||
outputs: [], | ||
}, | ||
{ | ||
hasher: mockHasher, | ||
} as unknown as HasherContext, | ||
); | ||
expect(hash).toEqual({ value: 'hashed-task' }); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
import { CustomHasher } from '@nx/devkit'; | ||
|
||
/** | ||
* This is a boilerplate custom hasher that matches | ||
* the default Nx hasher. If you need to extend the behavior, | ||
* you can consume workspace details from the context. | ||
*/ | ||
export const bundleHasher: CustomHasher = async (task, context) => { | ||
return context.hasher.hashTask(task, context.taskGraph); | ||
}; | ||
|
||
export default bundleHasher; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
export interface BundleExecutorSchema { | ||
main: string; | ||
outputPath: string; | ||
} // eslint-disable-line |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
{ | ||
"$schema": "https://json-schema.org/schema", | ||
"version": 2, | ||
"title": "Bundle executor", | ||
"description": "Post processor for Angular's esbuild builder to reduce chunks", | ||
"type": "object", | ||
"properties": { | ||
"main": { | ||
"type": "string", | ||
"description": "The path to the entry file, relative to project.", | ||
"alias": "entryFile", | ||
"x-completion-type": "file", | ||
"x-completion-glob": "**/*@(.js|.ts)", | ||
"x-priority": "important" | ||
} | ||
}, | ||
"required": [] | ||
} |