diff --git a/packages/angular_devkit/build_angular/test/browser/web-worker_spec_large.ts b/packages/angular_devkit/build_angular/test/browser/web-worker_spec_large.ts
index a7373d110fd0..711a9267e118 100644
--- a/packages/angular_devkit/build_angular/test/browser/web-worker_spec_large.ts
+++ b/packages/angular_devkit/build_angular/test/browser/web-worker_spec_large.ts
@@ -26,6 +26,8 @@ describe('Browser Builder Web Worker support', () => {
const workerFiles: { [k: string]: string } = {
'src/app/dep.ts': `export const foo = 'bar';`,
'src/app/app.worker.ts': `
+ ///
+
import { foo } from './dep';
console.log('hello from worker');
addEventListener('message', ({ data }) => {
diff --git a/packages/schematics/angular/web-worker/files/project-tsconfig/tsconfig.json.template b/packages/schematics/angular/web-worker/files/project-tsconfig/tsconfig.json.template
deleted file mode 100644
index b170f6d1d0e5..000000000000
--- a/packages/schematics/angular/web-worker/files/project-tsconfig/tsconfig.json.template
+++ /dev/null
@@ -1,10 +0,0 @@
-{
- "extends": "<%= relativePathToWorkspaceRoot %>/tsconfig.json",
- "compilerOptions": {
- "lib": [
- "es2018",
- "dom",
- "webworker"
- ],
- }
-}
diff --git a/packages/schematics/angular/web-worker/files/worker-tsconfig/tsconfig.worker.json.template b/packages/schematics/angular/web-worker/files/worker-tsconfig/tsconfig.worker.json.template
index 33b92e255762..166d26bac399 100644
--- a/packages/schematics/angular/web-worker/files/worker-tsconfig/tsconfig.worker.json.template
+++ b/packages/schematics/angular/web-worker/files/worker-tsconfig/tsconfig.worker.json.template
@@ -1,5 +1,5 @@
{
- "extends": "./tsconfig.json",
+ "extends": "<%= relativePathToWorkspaceRoot %>/tsconfig.json",
"compilerOptions": {
"outDir": "<%= relativePathToWorkspaceRoot %>/out-tsc/worker",
"lib": [
@@ -9,6 +9,6 @@
"types": []
},
"include": [
- "**/*.worker.ts"
+ "src/**/*.worker.ts"
]
}
diff --git a/packages/schematics/angular/web-worker/files/worker/__name@dasherize__.worker.ts.template b/packages/schematics/angular/web-worker/files/worker/__name@dasherize__.worker.ts.template
index 27020fe12b04..b7049b0b80c6 100644
--- a/packages/schematics/angular/web-worker/files/worker/__name@dasherize__.worker.ts.template
+++ b/packages/schematics/angular/web-worker/files/worker/__name@dasherize__.worker.ts.template
@@ -1,3 +1,5 @@
+///
+
addEventListener('message', ({ data }) => {
const response = `worker response to ${data}`;
postMessage(response);
diff --git a/packages/schematics/angular/web-worker/index.ts b/packages/schematics/angular/web-worker/index.ts
index 25912657a876..92e6df7ff45c 100644
--- a/packages/schematics/angular/web-worker/index.ts
+++ b/packages/schematics/angular/web-worker/index.ts
@@ -5,7 +5,7 @@
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
-import { JsonParseMode, parseJsonAst, strings, tags } from '@angular-devkit/core';
+import { JsonParseMode, join, normalize, parseJsonAst, strings, tags } from '@angular-devkit/core';
import {
Rule, SchematicContext, SchematicsException, Tree,
apply, applyTemplates, chain, mergeWith, move, noop, url,
@@ -21,54 +21,16 @@ function addConfig(options: WebWorkerOptions, root: string, tsConfigPath: string
return (host: Tree, context: SchematicContext) => {
context.logger.debug('updating project configuration.');
- const tsConfigRules = [];
-
- // Add tsconfig.worker.json.
- const relativePathToWorkspaceRoot = root.split('/').map(x => '..').join('/');
- tsConfigRules.push(mergeWith(apply(url('./files/worker-tsconfig'), [
- applyTemplates({ ...options, relativePathToWorkspaceRoot }),
- move(root),
- ])));
-
- // Add project tsconfig.json.
- // The project level tsconfig.json with webworker lib is for editor support since
- // the dom and webworker libs are mutually exclusive.
- // Note: this schematic does not change other tsconfigs to use the project-level tsconfig.
- const projectTsConfigPath = `${root}/tsconfig.json`;
- if (host.exists(projectTsConfigPath)) {
- // If the file already exists, alter it.
- const buffer = host.read(projectTsConfigPath);
- if (buffer) {
- const tsCfgAst = parseJsonAst(buffer.toString(), JsonParseMode.Loose);
- if (tsCfgAst.kind != 'object') {
- throw new SchematicsException('Invalid tsconfig. Was expecting an object');
- }
- const optsAstNode = findPropertyInAstObject(tsCfgAst, 'compilerOptions');
- if (optsAstNode && optsAstNode.kind != 'object') {
- throw new SchematicsException(
- 'Invalid tsconfig "compilerOptions" property; Was expecting an object.');
- }
- const libAstNode = findPropertyInAstObject(tsCfgAst, 'lib');
- if (libAstNode && libAstNode.kind != 'array') {
- throw new SchematicsException('Invalid tsconfig "lib" property; expected an array.');
- }
- const newLibProp = 'webworker';
- if (libAstNode && !libAstNode.value.includes(newLibProp)) {
- const recorder = host.beginUpdate(projectTsConfigPath);
- appendValueInAstArray(recorder, libAstNode, newLibProp);
- host.commitUpdate(recorder);
- }
- }
- } else {
- // Otherwise create it.
- tsConfigRules.push(mergeWith(apply(url('./files/project-tsconfig'), [
- applyTemplates({ ...options, relativePathToWorkspaceRoot }),
- move(root),
- ])));
- }
+ // todo: replace with the new helper method in a seperate PR
+ // https://github.com/angular/angular-cli/pull/14207
+ const rootNormalized = root.endsWith('/') ? root.slice(0, -1) : root;
+ const relativePathToWorkspaceRoot =
+ rootNormalized
+ ? rootNormalized.split('/').map(x => '..').join('/')
+ : '.';
// Add worker glob exclusion to tsconfig.app.json.
- const workerGlob = '**/*.worker.ts';
+ const workerGlob = 'src/**/*.worker.ts';
const buffer = host.read(tsConfigPath);
if (buffer) {
const tsCfgAst = parseJsonAst(buffer.toString(), JsonParseMode.Loose);
@@ -80,17 +42,19 @@ function addConfig(options: WebWorkerOptions, root: string, tsConfigPath: string
throw new SchematicsException('Invalid tsconfig "exclude" property; expected an array.');
}
- if (filesAstNode && filesAstNode.value.indexOf(workerGlob) == -1) {
+ if (filesAstNode && !filesAstNode.value.includes(workerGlob)) {
const recorder = host.beginUpdate(tsConfigPath);
appendValueInAstArray(recorder, filesAstNode, workerGlob);
host.commitUpdate(recorder);
}
}
- return chain([
- // Add tsconfigs.
- ...tsConfigRules,
- ]);
+ return mergeWith(
+ apply(url('./files/worker-tsconfig'), [
+ applyTemplates({ ...options, relativePathToWorkspaceRoot }),
+ move(root),
+ ]),
+ );
};
}
@@ -145,7 +109,7 @@ export default function (options: WebWorkerOptions): Rule {
throw new SchematicsException('Option "project" is required.');
}
if (!options.target) {
- throw new SchematicsException('Option (target) is required.');
+ throw new SchematicsException('Option "target" is required.');
}
const project = workspace.projects.get(options.project);
@@ -169,11 +133,11 @@ export default function (options: WebWorkerOptions): Rule {
const parsedPath = parseName(options.path, options.name);
options.name = parsedPath.name;
options.path = parsedPath.path;
- const root = project.root || project.sourceRoot || '';
+ const root = project.root || '';
const needWebWorkerConfig = !projectTargetOptions.webWorkerTsConfig;
if (needWebWorkerConfig) {
- const workerConfigPath = `${root.endsWith('/') ? root : root + '/'}tsconfig.worker.json`;
+ const workerConfigPath = join(normalize(root), 'tsconfig.worker.json');
projectTargetOptions.webWorkerTsConfig = workerConfigPath;
// add worker tsconfig to lint architect target
diff --git a/packages/schematics/angular/web-worker/index_spec.ts b/packages/schematics/angular/web-worker/index_spec.ts
index 25ef32d9a9b5..bc68cba035d5 100644
--- a/packages/schematics/angular/web-worker/index_spec.ts
+++ b/packages/schematics/angular/web-worker/index_spec.ts
@@ -20,7 +20,6 @@ describe('Service Worker Schematic', () => {
project: 'bar',
target: 'build',
name: 'app',
- // path: 'src/app',
snippet: true,
};
@@ -54,18 +53,14 @@ describe('Service Worker Schematic', () => {
expect(tree.exists(path)).toEqual(true);
});
- it('should put a new tsconfig.json file in the project root', async () => {
- const tree = await schematicRunner.runSchematicAsync('web-worker', defaultOptions, appTree)
- .toPromise();
- const path = '/projects/bar/tsconfig.json';
- expect(tree.exists(path)).toEqual(true);
- });
-
it('should put the tsconfig.worker.json file in the project root', async () => {
const tree = await schematicRunner.runSchematicAsync('web-worker', defaultOptions, appTree)
.toPromise();
const path = '/projects/bar/tsconfig.worker.json';
expect(tree.exists(path)).toEqual(true);
+
+ const { compilerOptions } = JSON.parse(tree.readContent(path));
+ expect(compilerOptions.outDir).toBe('../../out-tsc/worker');
});
it('should add the webWorkerTsConfig option to workspace', async () => {
@@ -80,7 +75,7 @@ describe('Service Worker Schematic', () => {
const tree = await schematicRunner.runSchematicAsync('web-worker', defaultOptions, appTree)
.toPromise();
const { exclude } = JSON.parse(tree.readContent('/projects/bar/tsconfig.app.json'));
- expect(exclude).toContain('**/*.worker.ts');
+ expect(exclude).toContain('src/**/*.worker.ts');
});
it('should add snippet to sibling file', async () => {
@@ -103,4 +98,20 @@ describe('Service Worker Schematic', () => {
'projects/bar/tsconfig.worker.json',
]);
});
+
+ it(`should add 'tsconfig.worker.json' outside of 'src' directory in root app`, async () => {
+ const rootAppOptions = { ...appOptions, projectRoot: '', name: 'foo' };
+ const workerOptions = { ...defaultOptions, project: 'foo' };
+
+ appTree = await schematicRunner.runSchematicAsync('application', rootAppOptions, appTree)
+ .toPromise();
+ const tree = await schematicRunner.runSchematicAsync('web-worker', workerOptions, appTree)
+ .toPromise();
+
+ const path = '/tsconfig.worker.json';
+ expect(tree.exists(path)).toEqual(true);
+
+ const { compilerOptions } = JSON.parse(tree.readContent(path));
+ expect(compilerOptions.outDir).toBe('./out-tsc/worker');
+ });
});
diff --git a/tests/legacy-cli/e2e/tests/build/worker.ts b/tests/legacy-cli/e2e/tests/build/worker.ts
index 7c9398687af6..759bb57e36c8 100644
--- a/tests/legacy-cli/e2e/tests/build/worker.ts
+++ b/tests/legacy-cli/e2e/tests/build/worker.ts
@@ -14,8 +14,8 @@ export default async function () {
const workerPath = join('src', 'app', 'app.worker.ts');
const snippetPath = join('src', 'app', 'app.component.ts');
- const projectTsConfig = join('src', 'tsconfig.json');
- const workerTsConfig = join('src', 'tsconfig.worker.json');
+ const projectTsConfig = 'tsconfig.json';
+ const workerTsConfig = 'tsconfig.worker.json';
await ng('generate', 'web-worker', 'app');
await expectFileToExist(workerPath);