Skip to content

Commit

Permalink
fix(localize): install @angular/localize in devDependencies by de…
Browse files Browse the repository at this point in the history
…fault

Previously this package was installed in the default `dependencies` section
of `package.json`, but this meant that its dependencies are treated as
dependencies of the main project - Babel, for example.

Generally, $localize` is not used at runtime - it is compiled out by the
translation tooling, so there is no need for it to be a full dependency.

This commit changes the default location of the package to be the
`devDependencies` section, but gives the user a prompt to choose
otherwise.

Fixes angular#38329
  • Loading branch information
petebacondarwin committed Sep 2, 2020
1 parent 59c234c commit 171b5bb
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 3 deletions.
6 changes: 5 additions & 1 deletion packages/localize/schematics/ng-add/README.md
Expand Up @@ -3,4 +3,8 @@
This schematic will be executed when an Angular CLI user runs `ng add @angular/localize`.

It will search their `angular.json` file, and find polyfills and main files for server builders.
Then it will add the `@angular/localize/init` polyfill that `@angular/localize` needs to work.
Then it will add the `@angular/localize/init` polyfill that `@angular/localize` needs to work.

If the user specifies that they want to use `$localize` at runtime then the dependency will be
added to the `depdendencies` section of `package.json` rather than in the `devDependencies` which
is the default.
24 changes: 24 additions & 0 deletions packages/localize/schematics/ng-add/index.ts
Expand Up @@ -10,6 +10,8 @@

import {virtualFs, workspaces} from '@angular-devkit/core';
import {chain, Rule, SchematicsException, Tree} from '@angular-devkit/schematics';
import {NodePackageInstallTask} from '@angular-devkit/schematics/tasks';
import {addPackageJsonDependency, NodeDependencyType, removePackageJsonDependency} from '@schematics/angular/utility/dependencies';
import {getWorkspace} from '@schematics/angular/utility/workspace';
import {Builders} from '@schematics/angular/utility/workspace-models';

Expand Down Expand Up @@ -95,6 +97,22 @@ function prependToTargetFiles(
};
}

function moveToDependencyType(type: NodeDependencyType): Rule {
return (host, context) => {
debugger;
if (host.exists('package.json')) {
// Remove the previous dependency and add in a new one under the desired type.
removePackageJsonDependency(host, '@angular/localize');
addPackageJsonDependency(
host, {name: '@angular/localize', type, version: `^0.0.0-PLACEHOLDER`});

// Add a task to run the package manager. This is necessary because we updated
// "package.json" and we want lock files to reflect this.
context.addTask(new NodePackageInstallTask());
};
};
}

export default function(options: Schema): Rule {
return async (host: Tree) => {
if (!options.name) {
Expand All @@ -114,9 +132,15 @@ export default function(options: Schema): Rule {
${localizePolyfill}
`;

// If `$localize` will not be used at runtime then we can install `@angular/localize` as a
// devDependency.
const dependencyType =
options.useAtRuntime ? NodeDependencyType.Default : NodeDependencyType.Dev;

return chain([
prependToTargetFiles(project, Builders.Browser, 'polyfills', localizeStr),
prependToTargetFiles(project, Builders.Server, 'main', localizeStr),
moveToDependencyType(dependencyType),
]);
};
}
23 changes: 23 additions & 0 deletions packages/localize/schematics/ng-add/index_spec.ts
Expand Up @@ -33,6 +33,11 @@ export { renderModule, renderModuleFactory } from '@angular/platform-server';`;

beforeEach(() => {
host = new UnitTestTree(new HostTree());
host.create('package.json', `{
"dependencies": {
"@angular/localize": "old-version"
}
}`);
host.create('src/polyfills.ts', polyfillsContent);
host.create('src/another-polyfills.ts', polyfillsContent);
host.create('src/unrelated-polyfills.ts', polyfillsContent);
Expand Down Expand Up @@ -166,4 +171,22 @@ export { renderModule, renderModuleFactory } from '@angular/platform-server';`;
}));
await schematicRunner.runSchematicAsync('ng-add', defaultOptions, host).toPromise();
});

it('should add package to `devDependencies` by default', async () => {
host = await schematicRunner.runSchematicAsync('ng-add', defaultOptions, host).toPromise();
const packageJsonText = host.readContent('/package.json');
expect(JSON.parse(packageJsonText).devDependencies?.['@angular/localize'])
.toBe('^0.0.0-PLACEHOLDER');
expect(JSON.parse(packageJsonText).dependencies?.['@angular/localize']).toBeUndefined();
});

it('should add package to `dependencies` if `useAtRuntime` is `true`', async () => {
host = await schematicRunner
.runSchematicAsync('ng-add', {...defaultOptions, useAtRuntime: true}, host)
.toPromise();
const packageJsonText = host.readContent('/package.json');
expect(JSON.parse(packageJsonText).dependencies?.['@angular/localize'])
.toBe('^0.0.0-PLACEHOLDER');
expect(JSON.parse(packageJsonText).devDependencies?.['@angular/localize']).toBeUndefined();
});
});
7 changes: 7 additions & 0 deletions packages/localize/schematics/ng-add/schema.d.ts
Expand Up @@ -11,4 +11,11 @@ export interface Schema {
* The name of the project.
*/
name?: string;
/**
* Will this project use $localize at runtime?
*
* If true then the dependency is included in the `dependencies` section of packge.json, rather
* than `devDependencies`.
*/
useAtRuntime?: boolean;
}
8 changes: 6 additions & 2 deletions packages/localize/schematics/ng-add/schema.json
Expand Up @@ -10,8 +10,12 @@
"$default": {
"$source": "projectName"
}
},
"useAtRuntime": {
"type": "boolean",
"description": "If true then the dependency is included in the `dependencies` section of packge.json, rather than `devDependencies`.",
"x-prompt": "Will this project use $localize at runtime?"
}
},
"required": [
]
"required": []
}

0 comments on commit 171b5bb

Please sign in to comment.