diff --git a/packages/localize/package.json b/packages/localize/package.json index 37a802f06c5af..318f3b51a32da 100644 --- a/packages/localize/package.json +++ b/packages/localize/package.json @@ -16,6 +16,9 @@ "ng-update": { "packageGroup": "NG_UPDATE_PACKAGE_GROUP" }, + "ng-add": { + "save": "devDependencies" + }, "sideEffects": [ "**/init/index.js", "**/init.js", @@ -36,4 +39,4 @@ "publishConfig": { "registry": "https://wombat-dressing-room.appspot.com" } -} \ No newline at end of file +} diff --git a/packages/localize/schematics/ng-add/README.md b/packages/localize/schematics/ng-add/README.md index e6078ad36ae3c..394ff4ef8a59d 100644 --- a/packages/localize/schematics/ng-add/README.md +++ b/packages/localize/schematics/ng-add/README.md @@ -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. \ No newline at end of file +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. \ No newline at end of file diff --git a/packages/localize/schematics/ng-add/index.ts b/packages/localize/schematics/ng-add/index.ts index 823c68b0ca8d3..91c14dea2dd4e 100644 --- a/packages/localize/schematics/ng-add/index.ts +++ b/packages/localize/schematics/ng-add/index.ts @@ -9,7 +9,9 @@ */ import {virtualFs, workspaces} from '@angular-devkit/core'; -import {chain, Rule, SchematicsException, Tree} from '@angular-devkit/schematics'; +import {chain, noop, Rule, SchematicContext, 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'; @@ -95,6 +97,22 @@ function prependToTargetFiles( }; } +function moveToDependencies(host: Tree, context: SchematicContext) { + 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: NodeDependencyType.Default, + 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) { @@ -117,6 +135,9 @@ ${localizePolyfill} return chain([ prependToTargetFiles(project, Builders.Browser, 'polyfills', localizeStr), prependToTargetFiles(project, Builders.Server, 'main', localizeStr), + // If `$localize` will be used at runtime then must install `@angular/localize` + // into `dependencies`, rather than the default of `devDependencies`. + options.useAtRuntime ? moveToDependencies : noop() ]); }; } diff --git a/packages/localize/schematics/ng-add/index_spec.ts b/packages/localize/schematics/ng-add/index_spec.ts index 5f5690f4ffd25..fabd645919a8c 100644 --- a/packages/localize/schematics/ng-add/index_spec.ts +++ b/packages/localize/schematics/ng-add/index_spec.ts @@ -33,6 +33,13 @@ export { renderModule, renderModuleFactory } from '@angular/platform-server';`; beforeEach(() => { host = new UnitTestTree(new HostTree()); + host.create('package.json', JSON.stringify({ + 'devDependencies': { + // The default (according to `ng-add` in its package.json) is for `@angular/localize` to be + // saved to `devDependencies`. + '@angular/localize': '~0.0.0-PLACEHOLDER', + } + })); host.create('src/polyfills.ts', polyfillsContent); host.create('src/another-polyfills.ts', polyfillsContent); host.create('src/unrelated-polyfills.ts', polyfillsContent); @@ -166,4 +173,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(); + }); }); diff --git a/packages/localize/schematics/ng-add/schema.d.ts b/packages/localize/schematics/ng-add/schema.d.ts index d7bb6dc32610f..a96090d97e1e5 100644 --- a/packages/localize/schematics/ng-add/schema.d.ts +++ b/packages/localize/schematics/ng-add/schema.d.ts @@ -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; } diff --git a/packages/localize/schematics/ng-add/schema.json b/packages/localize/schematics/ng-add/schema.json index 775cbfcb51999..1c255911ce87b 100644 --- a/packages/localize/schematics/ng-add/schema.json +++ b/packages/localize/schematics/ng-add/schema.json @@ -10,8 +10,12 @@ "$default": { "$source": "projectName" } + }, + "useAtRuntime": { + "type": "boolean", + "description": "If set then `@angular/localize` is included in the `dependencies` section of `package.json`, rather than `devDependencies`, which is the default.", + "default": false } }, - "required": [ - ] + "required": [] }