Skip to content

Commit

Permalink
fix(angular): prevent creating stylesheet worker multiple times in ng…
Browse files Browse the repository at this point in the history
…-packagr executors (#22491)
  • Loading branch information
leosvelperez committed Mar 25, 2024
1 parent 814a12d commit 0429728
Show file tree
Hide file tree
Showing 2 changed files with 119 additions and 4 deletions.
Original file line number Diff line number Diff line change
@@ -1,9 +1,20 @@
import { FactoryProvider } from 'injection-js';
import type { FactoryProvider } from 'injection-js';
import { STYLESHEET_PROCESSOR_TOKEN } from 'ng-packagr/lib/styles/stylesheet-processor.di';
import { StylesheetProcessor } from './stylesheet-processor';
import { getInstalledPackageVersionInfo } from '../angular-version-utils';
import {
AsyncStylesheetProcessor,
StylesheetProcessor,
} from './stylesheet-processor';

export const STYLESHEET_PROCESSOR: FactoryProvider = {
provide: STYLESHEET_PROCESSOR_TOKEN,
useFactory: () => StylesheetProcessor,
useFactory: () => {
const { version: ngPackagrVersion } =
getInstalledPackageVersionInfo('ng-packagr');

return ngPackagrVersion !== '17.2.0'
? StylesheetProcessor
: AsyncStylesheetProcessor;
},
deps: [],
};
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,110 @@ export class StylesheetProcessor {
];
}

async process({
filePath,
content,
}: {
filePath: string;
content: string;
}): Promise<string> {
this.createRenderWorker();

return this.renderWorker.run({ content, filePath });
}

/** Destory workers in pool. */
destroy(): void {
void this.renderWorker?.destroy();
}

private createRenderWorker(): Promise<void> {
if (this.renderWorker) {
return;
}

const styleIncludePaths = [...this.includePaths];
let prevDir = null;
let currentDir = this.basePath;

while (currentDir !== prevDir) {
const p = join(currentDir, 'node_modules');
if (existsSync(p)) {
styleIncludePaths.push(p);
}

prevDir = currentDir;
currentDir = dirname(prevDir);
}

const browserslistData = browserslist(undefined, { path: this.basePath });

const { version: ngPackagrVersion } =
getInstalledPackageVersionInfo('ng-packagr');
let postcssConfiguration: PostcssConfiguration | undefined;
if (gte(ngPackagrVersion, '17.3.0')) {
const {
loadPostcssConfiguration,
} = require('ng-packagr/lib/styles/postcss-configuration');
postcssConfiguration = loadPostcssConfiguration(this.projectBasePath);
}

this.renderWorker = new Piscina({
filename: require.resolve(
'ng-packagr/lib/styles/stylesheet-processor-worker'
),
maxThreads,
env: {
...process.env,
FORCE_COLOR: '' + colors.enabled,
},
workerData: {
postcssConfiguration,
tailwindConfigPath: getTailwindConfigPath(
this.projectBasePath,
workspaceRoot
),
projectBasePath: this.projectBasePath,
browserslistData,
targets: transformSupportedBrowsersToTargets(browserslistData),
cacheDirectory: this.cacheDirectory,
cssUrl: this.cssUrl,
styleIncludePaths,
},
});
}
}

/**
* This class is used when ng-packagr version is 17.2.0. The async `loadPostcssConfiguration` function
* introduced in ng-packagr 17.2.0 causes a memory leak due to multiple workers being created. We must
* keep this class to support any workspace that might be using ng-packagr 17.2.0 where that function
* need to be awaited.
*/
export class AsyncStylesheetProcessor {
private renderWorker: typeof Piscina | undefined;

constructor(
private readonly projectBasePath: string,
private readonly basePath: string,
private readonly cssUrl?: CssUrl,
private readonly includePaths?: string[],
private readonly cacheDirectory?: string | false
) {
// By default, browserslist defaults are too inclusive
// https://github.com/browserslist/browserslist/blob/83764ea81ffaa39111c204b02c371afa44a4ff07/index.js#L516-L522
// We change the default query to browsers that Angular support.
// https://angular.io/guide/browser-support
(browserslist.defaults as string[]) = [
'last 2 Chrome versions',
'last 1 Firefox version',
'last 2 Edge major versions',
'last 2 Safari major versions',
'last 2 iOS major versions',
'Firefox ESR',
];
}

async process({
filePath,
content,
Expand Down Expand Up @@ -94,7 +198,7 @@ export class StylesheetProcessor {
const { version: ngPackagrVersion } =
getInstalledPackageVersionInfo('ng-packagr');
let postcssConfiguration: PostcssConfiguration | undefined;
if (gte(ngPackagrVersion, '17.2.0')) {
if (ngPackagrVersion === '17.2.0') {
const { loadPostcssConfiguration } = await import(
'ng-packagr/lib/styles/postcss-configuration'
);
Expand Down

0 comments on commit 0429728

Please sign in to comment.