Skip to content

Commit

Permalink
feat(angular): add migration to explicitly set `@angular/localize/ini…
Browse files Browse the repository at this point in the history
…t` polyfill (#28881)

Upstream change:
angular/angular-cli@d6a3403

<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->

<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->

<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->

## Current Behavior
<!-- This is the behavior we have today -->

## Expected Behavior
<!-- This is the behavior we should expect with the changes in this PR
-->

## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->

Fixes #
  • Loading branch information
leosvelperez authored Nov 11, 2024
1 parent 6a593dd commit e7af82c
Show file tree
Hide file tree
Showing 3 changed files with 186 additions and 0 deletions.
9 changes: 9 additions & 0 deletions packages/angular/migrations.json
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,15 @@
},
"description": "Update the @angular/cli package version to ~19.0.0-rc.1.",
"factory": "./src/migrations/update-20-2-0/update-angular-cli"
},
"add-localize-polyfill-to-targets": {
"cli": "nx",
"version": "20.2.0-beta.0",
"requires": {
"@angular/core": ">=19.0.0-rc.1"
},
"description": "Add the '@angular/localize/init' polyfill to the 'polyfills' option of targets using esbuild-based executors.",
"factory": "./src/migrations/update-20-2-0/add-localize-polyfill-to-targets"
}
},
"packageJsonUpdates": {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
import {
addProjectConfiguration,
readProjectConfiguration,
type Tree,
} from '@nx/devkit';
import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing';
import migration, {
executorsToAddPolyfillTo,
} from './add-localize-polyfill-to-targets';

describe('add-localize-polyfill-to-targets migration', () => {
let tree: Tree;

beforeEach(() => {
tree = createTreeWithEmptyWorkspace();
});

test.each(executorsToAddPolyfillTo)(
'should add the "@angular/localize/init" polyfill when using the "%s" executor and the "localize" option is enabled',
async (executor) => {
addProjectConfiguration(tree, 'app1', {
root: 'apps/app1',
projectType: 'application',
targets: { build: { executor, options: { localize: true } } },
});

await migration(tree);

const project = readProjectConfiguration(tree, 'app1');
expect(project.targets.build.options.polyfills).toStrictEqual([
'@angular/localize/init',
]);
}
);

test.each(executorsToAddPolyfillTo)(
'should add the "@angular/localize/init" polyfill when using the "%s" executor and the "localize" option is enabled in a configuration',
async (executor) => {
addProjectConfiguration(tree, 'app1', {
root: 'apps/app1',
projectType: 'application',
targets: {
build: {
executor,
configurations: { production: { localize: true } },
},
},
});

await migration(tree);

const project = readProjectConfiguration(tree, 'app1');
expect(project.targets.build.options.polyfills).toStrictEqual([
'@angular/localize/init',
]);
}
);

test.each(executorsToAddPolyfillTo)(
'should not duplicate the "@angular/localize/init" polyfill when using the "%s" executor and the polyfill is already present',
async (executor) => {
addProjectConfiguration(tree, 'app1', {
root: 'apps/app1',
projectType: 'application',
targets: {
build: {
executor,
options: { localize: true, polyfills: ['@angular/localize/init'] },
},
},
});

await migration(tree);

const project = readProjectConfiguration(tree, 'app1');
expect(project.targets.build.options.polyfills).toStrictEqual([
'@angular/localize/init',
]);
}
);

test.each(executorsToAddPolyfillTo)(
'should not add the "@angular/localize/init" polyfill when using the "%s" executor and the "localize" option is disabled',
async (executor) => {
addProjectConfiguration(tree, 'app1', {
root: 'apps/app1',
projectType: 'application',
targets: { build: { executor, options: { localize: false } } },
});

await migration(tree);

const project = readProjectConfiguration(tree, 'app1');
expect(project.targets.build.options.polyfills).toBeUndefined();
}
);

test('should not add the "@angular/localize/init" polyfill when not using one of the targeted executors', async () => {
addProjectConfiguration(tree, 'app1', {
root: 'apps/app1',
projectType: 'application',
targets: {
build: {
executor: '@my-org/some:awesome-executor',
options: { localize: true },
},
},
});

await migration(tree);

const project = readProjectConfiguration(tree, 'app1');
expect(project.targets.build.options.polyfills).toBeUndefined();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import {
formatFiles,
getProjects,
updateProjectConfiguration,
type Tree,
} from '@nx/devkit';
import { allTargetOptions } from '../../utils/targets';

export const executorsToAddPolyfillTo = [
'@angular/build:application',
'@angular-devkit/build-angular:application',
'@nx/angular:application',
'@angular-devkit/build-angular:browser-esbuild',
'@nx/angular:browser-esbuild',
];

export default async function (tree: Tree) {
const projects = getProjects(tree);

for (const [projectName, project] of projects) {
if (project.projectType !== 'application') {
continue;
}

let isUpdated = false;
for (const target of Object.values(project.targets ?? {})) {
if (!executorsToAddPolyfillTo.includes(target.executor)) {
continue;
}

const polyfills = target.options?.['polyfills'];
if (
Array.isArray(polyfills) &&
polyfills.some(
(polyfill) =>
typeof polyfill === 'string' &&
polyfill.startsWith('@angular/localize')
)
) {
// the polyfill is already present, skip
continue;
}

// Only add '@angular/localize/init' polyfill if 'localize' option is enabled
for (const [, options] of allTargetOptions(target)) {
if (options['localize']) {
target.options ??= {};
target.options['polyfills'] ??= [];
target.options['polyfills'].push('@angular/localize/init');
isUpdated = true;
break;
}
}
}

if (isUpdated) {
updateProjectConfiguration(tree, projectName, project);
}
}

await formatFiles(tree);
}

0 comments on commit e7af82c

Please sign in to comment.