diff --git a/packages/schematics/angular/service-worker/index.ts b/packages/schematics/angular/service-worker/index.ts index c0437bad5774..2e82f7135400 100644 --- a/packages/schematics/angular/service-worker/index.ts +++ b/packages/schematics/angular/service-worker/index.ts @@ -10,7 +10,6 @@ import { SchematicContext, SchematicsException, Tree, - UpdateRecorder, apply, chain, mergeWith, @@ -54,13 +53,14 @@ function getProjectConfiguration( return applyTo; } -function updateConfigFile(options: ServiceWorkerOptions): Rule { +function updateConfigFile(options: ServiceWorkerOptions, root: string): Rule { return (host: Tree, context: SchematicContext) => { context.logger.debug('updating config file.'); const workspace = getWorkspace(host); const config = getProjectConfiguration(workspace, options); config.serviceWorker = true; + config.ngswConfigPath = `${root.endsWith('/') ? root : root + '/'}ngsw-config.json`; return updateWorkspace(workspace); }; @@ -103,8 +103,7 @@ function updateAppModule(options: ServiceWorkerOptions): Rule { let importModule = 'ServiceWorkerModule'; let importPath = '@angular/service-worker'; if (!isImported(moduleSource, importModule, importPath)) { - const change = insertImport - (moduleSource, modulePath, importModule, importPath); + const change = insertImport(moduleSource, modulePath, importModule, importPath); if (change) { const recorder = host.beginUpdate(modulePath); recorder.insertLeft((change as InsertChange).pos, (change as InsertChange).toAdd); @@ -119,8 +118,7 @@ function updateAppModule(options: ServiceWorkerOptions): Rule { // TODO: dynamically find environments relative path importPath = '../environments/environment'; if (!isImported(moduleSource, importModule, importPath)) { - const change = insertImport - (moduleSource, modulePath, importModule, importPath); + const change = insertImport(moduleSource, modulePath, importModule, importPath); if (change) { const recorder = host.beginUpdate(modulePath); recorder.insertLeft((change as InsertChange).pos, (change as InsertChange).toAdd); @@ -176,16 +174,17 @@ export default function (options: ServiceWorkerOptions): Rule { resourcesOutputPath = '/' + resourcesOutputPath.split('/').filter(x => !!x).join('/'); } + const root = project.root || project.sourceRoot || ''; const templateSource = apply(url('./files'), [ template({ ...options, resourcesOutputPath }), - move(project.root), + move(root), ]); context.addTask(new NodePackageInstallTask()); return chain([ mergeWith(templateSource), - updateConfigFile(options), + updateConfigFile(options, root), addDependencies(), updateAppModule(options), ]); diff --git a/packages/schematics/angular/service-worker/index_spec.ts b/packages/schematics/angular/service-worker/index_spec.ts index 24718e9fe576..0c9dfe3a52e2 100644 --- a/packages/schematics/angular/service-worker/index_spec.ts +++ b/packages/schematics/angular/service-worker/index_spec.ts @@ -96,6 +96,10 @@ describe('Service Worker Schematic', () => { const tree = schematicRunner.runSchematic('service-worker', defaultOptions, appTree); const path = '/projects/bar/ngsw-config.json'; expect(tree.exists(path)).toEqual(true); + + const { projects } = JSON.parse(tree.readContent('/angular.json')); + expect(projects.bar.architect.build.configurations.production.ngswConfigPath) + .toBe('projects/bar/ngsw-config.json'); }); it('should add root assets RegExp', () => { @@ -117,4 +121,25 @@ describe('Service Worker Schematic', () => { .toContain('/outDir/*.(eot|svg|cur|jpg|png|webp|gif|otf|ttf|woff|woff2|ani)'); }); + it('should generate ngsw-config.json in src when the application is at root level', () => { + const name = 'foo'; + const rootAppOptions: ApplicationOptions = { + ...appOptions, + name, + projectRoot: '', + }; + const rootSWOptions: ServiceWorkerOptions = { + ...defaultOptions, + project: name, + }; + + let tree = schematicRunner.runSchematic('application', rootAppOptions, appTree); + tree = schematicRunner.runSchematic('service-worker', rootSWOptions, tree); + expect(tree.exists('/src/ngsw-config.json')).toBe(true); + + const { projects } = JSON.parse(tree.readContent('/angular.json')); + expect(projects.foo.architect.build.configurations.production.ngswConfigPath) + .toBe('src/ngsw-config.json'); + }); + }); diff --git a/packages/schematics/angular/utility/workspace-models.ts b/packages/schematics/angular/utility/workspace-models.ts index a297922be73f..051354129d01 100644 --- a/packages/schematics/angular/utility/workspace-models.ts +++ b/packages/schematics/angular/utility/workspace-models.ts @@ -54,6 +54,7 @@ export interface BrowserBuilderOptions extends BrowserBuilderBaseOptions { extractLicenses?: boolean; vendorChunk?: boolean; buildOptimizer?: boolean; + ngswConfigPath?: string; budgets?: { type: string; maximumWarning?: string;