From c13f2e33110247c663d20544d49826b8f0b425ca Mon Sep 17 00:00:00 2001 From: Alan Agius Date: Thu, 3 Oct 2019 18:13:57 +0200 Subject: [PATCH] refactor: remove output path logic as it's handled in universal schematic If the outputPath change is needed, this should be done at upstream in `angular/cli` instead https://github.com/angular/angular-cli/blob/102cd86a8ea33bf1c3dc8cb75b8727c2f239c3d5/packages/schematics/angular/universal/index.ts#L42 --- modules/common/schematics/add/index.spec.ts | 8 +++ modules/common/schematics/add/index.ts | 58 ++++++------------- modules/common/schematics/utils/utils.ts | 34 +++++------ .../schematics/install/index.ts | 6 +- .../hapi-engine/schematics/install/index.ts | 6 +- package.json | 8 +-- yarn.lock | 50 ++++++++-------- 7 files changed, 77 insertions(+), 93 deletions(-) diff --git a/modules/common/schematics/add/index.spec.ts b/modules/common/schematics/add/index.spec.ts index ad6dc1c4e..792b522a3 100644 --- a/modules/common/schematics/add/index.spec.ts +++ b/modules/common/schematics/add/index.spec.ts @@ -41,6 +41,14 @@ describe('Add Schematic Rule', () => { expect(productionConfig.optimization).toBeDefined(); }); + it('should add scripts to package.json', async () => { + const tree = await schematicRunner + .callRule(addUniversalCommonRule(defaultOptions), appTree).toPromise(); + const {scripts} = JSON.parse(tree.read('package.json')!.toString()); + expect(scripts['build:ssr']).toBe('ng build --prod && ng run test-app:server:production'); + expect(scripts['serve:ssr']).toBe('node dist/test-app/server/main.js'); + }); + it(`should update 'tsconfig.server.json' files with main file`, async () => { const tree = await schematicRunner .callRule(addUniversalCommonRule(defaultOptions), appTree).toPromise(); diff --git a/modules/common/schematics/add/index.ts b/modules/common/schematics/add/index.ts index b0f32467d..a036bae48 100644 --- a/modules/common/schematics/add/index.ts +++ b/modules/common/schematics/add/index.ts @@ -12,14 +12,13 @@ import { SchematicsException, noop, } from '@angular-devkit/schematics'; -import {normalize, join, parseJsonAst, JsonParseMode} from '@angular-devkit/core'; -import {updateWorkspace} from '@schematics/angular/utility/workspace'; +import {parseJsonAst, JsonParseMode} from '@angular-devkit/core'; import { findPropertyInAstObject, appendValueInAstArray, } from '@schematics/angular/utility/json-utils'; import {Schema as UniversalOptions} from '@schematics/angular/universal/schema'; -import {stripTsExtension, getDistPaths, getProject} from '../utils'; +import {stripTsExtension, getOutputPath, getProject} from '../utils'; export interface AddUniversalOptions extends UniversalOptions { serverFileName?: string; @@ -35,7 +34,6 @@ export function addUniversalCommonRule(options: AddUniversalOptions): Rule { : externalSchematic('@schematics/angular', 'universal', options), addScriptsRule(options), updateServerTsConfigRule(options), - updateConfigFileRule(options), ]); }; } @@ -48,7 +46,7 @@ function addScriptsRule(options: AddUniversalOptions): Rule { throw new SchematicsException('Could not find package.json'); } - const {server: serverDist} = await getDistPaths(host, options.clientProject); + const serverDist = await getOutputPath(host, options.clientProject, 'server'); const pkg = JSON.parse(buffer.toString()); pkg.scripts = { ...pkg.scripts, @@ -60,42 +58,6 @@ function addScriptsRule(options: AddUniversalOptions): Rule { }; } -function updateConfigFileRule(options: AddUniversalOptions): Rule { - return host => { - return updateWorkspace((async workspace => { - const clientProject = workspace.projects.get(options.clientProject); - if (clientProject) { - const buildTarget = clientProject.targets.get('build'); - const serverTarget = clientProject.targets.get('server'); - - // We have to check if the project config has a server target, because - // if the Universal step in this schematic isn't run, it can't be guaranteed - // to exist - if (!serverTarget || !buildTarget) { - return; - } - - const distPaths = await getDistPaths(host, options.clientProject); - - serverTarget.options = { - ...serverTarget.options, - outputPath: distPaths.server, - }; - - serverTarget.options.main = join( - normalize(clientProject.root), - stripTsExtension(options.serverFileName) + '.ts', - ); - - buildTarget.options = { - ...buildTarget.options, - outputPath: distPaths.browser, - }; - } - })) as unknown as Rule; - }; -} - function updateServerTsConfigRule(options: AddUniversalOptions): Rule { return async host => { const clientProject = await getProject(host, options.clientProject); @@ -140,3 +102,17 @@ function updateServerTsConfigRule(options: AddUniversalOptions): Rule { } }; } + +export default function (options: UniversalOptions): Rule { + return async host => { + const clientProject = await getProject(host, options.clientProject); + + return chain([ + clientProject.targets.has('server') + ? noop() + : externalSchematic('@schematics/angular', 'universal', options), + addScriptsRule(options), + updateServerTsConfigRule(options), + ]); + }; +} diff --git a/modules/common/schematics/utils/utils.ts b/modules/common/schematics/utils/utils.ts index e81b6a8e2..b3979ef6f 100644 --- a/modules/common/schematics/utils/utils.ts +++ b/modules/common/schematics/utils/utils.ts @@ -7,7 +7,7 @@ */ import {Tree} from '@angular-devkit/schematics/src/tree/interface'; -import {workspaces, join, normalize} from '@angular-devkit/core'; +import {workspaces} from '@angular-devkit/core'; import {getWorkspace} from '@schematics/angular/utility/workspace'; import {SchematicsException} from '@angular-devkit/schematics'; @@ -29,24 +29,24 @@ export function stripTsExtension(file: string): string { return file.replace(/\.ts$/, ''); } -export async function getDistPaths(host: Tree, clientProjectName: string): Promise<{ - browser: string; - server: string; -}> { +export async function getOutputPath( + host: Tree, + projectName: string, + target: 'server' | 'build', +): Promise { // Generate new output paths - const clientProject = await getProject(host, clientProjectName); - const clientBuildTarget = clientProject.targets.get('build'); - if (!clientBuildTarget || !clientBuildTarget.options) { - throw new SchematicsException(`Cannot find 'options' for ${clientProjectName} build target.`); + const project = await getProject(host, projectName); + const serverTarget = project.targets.get(target); + if (!serverTarget || !serverTarget.options) { + throw new SchematicsException + (`Cannot find 'options' for ${projectName} ${target} target.`); } - const clientBuildOptions = clientBuildTarget.options; - const clientOutputPath = normalize( - typeof clientBuildOptions.outputPath === 'string' ? clientBuildOptions.outputPath : 'dist' - ); + const { outputPath } = serverTarget.options; + if (typeof outputPath !== 'string') { + throw new SchematicsException + (`outputPath for ${projectName} ${target} target is not a string.`); + } - return { - browser: join(clientOutputPath, 'browser'), - server: join(clientOutputPath, 'server'), - }; + return outputPath; } diff --git a/modules/express-engine/schematics/install/index.ts b/modules/express-engine/schematics/install/index.ts index 1104ecea3..252b17a57 100644 --- a/modules/express-engine/schematics/install/index.ts +++ b/modules/express-engine/schematics/install/index.ts @@ -26,7 +26,7 @@ import { import { getProject, stripTsExtension, - getDistPaths, + getOutputPath, } from '@nguniversal/common/schematics/utils'; import {addUniversalCommonRule} from '@nguniversal/common/schematics/add'; @@ -57,14 +57,14 @@ function addDependencies(options: UniversalOptions): Rule { export default function (options: UniversalOptions): Rule { return async (host: Tree) => { const clientProject = await getProject(host, options.clientProject); - const {browser} = await getDistPaths(host, options.clientProject); + const browserDistDirectory = await getOutputPath(host, options.clientProject, 'build'); const rootSource = apply(url('./files'), [ template({ ...strings, ...options, stripTsExtension, - browserDistDirectory: browser + browserDistDirectory, }), move(clientProject.root) ]); diff --git a/modules/hapi-engine/schematics/install/index.ts b/modules/hapi-engine/schematics/install/index.ts index dbd69d4a1..4ffb8337a 100644 --- a/modules/hapi-engine/schematics/install/index.ts +++ b/modules/hapi-engine/schematics/install/index.ts @@ -26,7 +26,7 @@ import { import { getProject, stripTsExtension, - getDistPaths, + getOutputPath, } from '@nguniversal/common/schematics/utils'; import {addUniversalCommonRule} from '@nguniversal/common/schematics/add'; @@ -62,14 +62,14 @@ function addDependencies(options: UniversalOptions): Rule { export default function (options: UniversalOptions): Rule { return async (host: Tree) => { const clientProject = await getProject(host, options.clientProject); - const {browser} = await getDistPaths(host, options.clientProject); + const browserDistDirectory = await getOutputPath(host, options.clientProject, 'build'); const rootSource = apply(url('./files'), [ template({ ...strings, ...options, stripTsExtension, - browserDistDirectory: browser + browserDistDirectory, }), move(clientProject.root) ]); diff --git a/package.json b/package.json index 98c49cc1c..75acdf4e3 100644 --- a/package.json +++ b/package.json @@ -47,9 +47,9 @@ "typescript": "~3.5.3" }, "devDependencies": { - "@angular-devkit/architect": "^0.900.0-next.6", - "@angular-devkit/core": "^9.0.0-next.6", - "@angular-devkit/schematics": "^9.0.0-next.6", + "@angular-devkit/architect": "^0.900.0-next.7", + "@angular-devkit/core": "^9.0.0-next.7", + "@angular-devkit/schematics": "^9.0.0-next.7", "@angular/bazel": "^9.0.0-next.8", "@bazel/bazel": "0.28.1", "@bazel/buildifier": "^0.25.1", @@ -58,7 +58,7 @@ "@bazel/jasmine": "^0.32.2", "@bazel/karma": "^0.32.2", "@bazel/typescript": "^0.32.2", - "@schematics/angular": "^9.0.0-next.6", + "@schematics/angular": "^9.0.0-next.7", "@types/express": "^4.0.39", "@types/fs-extra": "^4.0.5", "@types/hapi": "^17.0.12", diff --git a/yarn.lock b/yarn.lock index 1a9124787..b2437329f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10,12 +10,12 @@ "@angular-devkit/core" "8.0.0-beta.18" rxjs "6.4.0" -"@angular-devkit/architect@^0.900.0-next.6": - version "0.900.0-next.6" - resolved "https://registry.yarnpkg.com/@angular-devkit/architect/-/architect-0.900.0-next.6.tgz#dbfd2d533fb50c8253ef5bc8fd6f8e57439ef499" - integrity sha512-82g5PUMuiPt7J6qGetrqyzIE3B3AoImx17UY/nsPffsLCt48xnMrnc7munayHBAVbE7XRDXYxVv1yrZX2msDzw== +"@angular-devkit/architect@^0.900.0-next.7": + version "0.900.0-next.7" + resolved "https://registry.yarnpkg.com/@angular-devkit/architect/-/architect-0.900.0-next.7.tgz#0295edd0b601d127cb77526d8fd293b1a8beb315" + integrity sha512-dJQTUM5LoiiKJBF/R5l4mTJTqTF16VvbwPUA+xCz0WBqvhqsoOSWfSvLUyO8I3Wk4/rGM9BhsSH3505nFZtnug== dependencies: - "@angular-devkit/core" "9.0.0-next.6" + "@angular-devkit/core" "9.0.0-next.7" rxjs "6.5.3" "@angular-devkit/core@8.0.0-beta.18", "@angular-devkit/core@^8.0.0-beta.15": @@ -29,14 +29,14 @@ rxjs "6.4.0" source-map "0.7.3" -"@angular-devkit/core@9.0.0-next.6", "@angular-devkit/core@^9.0.0-next.6": - version "9.0.0-next.6" - resolved "https://registry.yarnpkg.com/@angular-devkit/core/-/core-9.0.0-next.6.tgz#f8e47cb966177ccdd69c568689aa01c80bd1bc6d" - integrity sha512-01sSgdLcd0vIHNyiNQi77UZc6R9Pdp79tj/oCtWrqomtNgtyp4uNis5gP77PUCAYErtDUYznUb3Fh4oXeMrinw== +"@angular-devkit/core@9.0.0-next.7", "@angular-devkit/core@^9.0.0-next.7": + version "9.0.0-next.7" + resolved "https://registry.yarnpkg.com/@angular-devkit/core/-/core-9.0.0-next.7.tgz#3ec750cd4f5fe2ca598da1fd2726ee899346033c" + integrity sha512-T/4+fKx9oB5ixa9TtV3/OtlEzXWw1uNT8kLkS5yOj/ZC3XcaGbBzOKns2ELIHgBFjHIeVFLIi49gplRTUy0mNw== dependencies: ajv "6.10.2" fast-json-stable-stringify "2.0.0" - magic-string "0.25.3" + magic-string "0.25.4" rxjs "6.5.3" source-map "0.7.3" @@ -48,12 +48,12 @@ "@angular-devkit/core" "8.0.0-beta.18" rxjs "6.4.0" -"@angular-devkit/schematics@9.0.0-next.6", "@angular-devkit/schematics@^9.0.0-next.6": - version "9.0.0-next.6" - resolved "https://registry.yarnpkg.com/@angular-devkit/schematics/-/schematics-9.0.0-next.6.tgz#6b3a80b6793d9d95c3e6f4ccab522d94bc8579bc" - integrity sha512-4O6mwmXVaC/zroP38IfetocrkeZpiztaqzyWeD7BhB/ZacfhY6Pa/+Yqu116UdKsY6DEhoHCSfRWSaj0YRnlsQ== +"@angular-devkit/schematics@9.0.0-next.7", "@angular-devkit/schematics@^9.0.0-next.7": + version "9.0.0-next.7" + resolved "https://registry.yarnpkg.com/@angular-devkit/schematics/-/schematics-9.0.0-next.7.tgz#d353944ac034e6c3366578f5681c5244d8de1871" + integrity sha512-8+EDWa150isxTkBZ93odUcD32XBJMDLt8eaJDPZJRwJ+HDuwiEmPdP9EyCcuddd3Xx715fv3xFv5CU45t4bHbg== dependencies: - "@angular-devkit/core" "9.0.0-next.6" + "@angular-devkit/core" "9.0.0-next.7" rxjs "6.5.3" "@angular/animations@^9.0.0-next.8": @@ -377,13 +377,13 @@ "@angular-devkit/schematics" "8.0.0-beta.18" "@phenomnomnominal/tsquery" "3.0.0" -"@schematics/angular@^9.0.0-next.6": - version "9.0.0-next.6" - resolved "https://registry.yarnpkg.com/@schematics/angular/-/angular-9.0.0-next.6.tgz#282e01de4bcce08f7b7eefacc54d2cbb9ef40e75" - integrity sha512-02DMivnka1LWHgyeGQqErJtlefRPHxkOJwdhYjB6lVAyNEX38hIpROQJVrgw2fEL+WDTPw9mwtgddNs0g2CtTg== +"@schematics/angular@^9.0.0-next.7": + version "9.0.0-next.7" + resolved "https://registry.yarnpkg.com/@schematics/angular/-/angular-9.0.0-next.7.tgz#49b8e87afd0bc88ee0e3c0426ec55b60ea5c36a7" + integrity sha512-H1u1Q+26xQR2RrYkshWyRSNa3lp/mn/akjr0szkr28B6Q8deUvu0Dz83sdCfbMBYhsPBe9XIEQBUNNkgZ2RjUQ== dependencies: - "@angular-devkit/core" "9.0.0-next.6" - "@angular-devkit/schematics" "9.0.0-next.6" + "@angular-devkit/core" "9.0.0-next.7" + "@angular-devkit/schematics" "9.0.0-next.7" "@types/argparse@1.0.33": version "1.0.33" @@ -3161,10 +3161,10 @@ magic-string@0.25.2: dependencies: sourcemap-codec "^1.4.4" -magic-string@0.25.3: - version "0.25.3" - resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.25.3.tgz#34b8d2a2c7fec9d9bdf9929a3fd81d271ef35be9" - integrity sha512-6QK0OpF/phMz0Q2AxILkX2mFhi7m+WMwTRg0LQKq/WBB0cDP4rYH3Wp4/d3OTXlrPLVJT/RFqj8tFeAR4nk8AA== +magic-string@0.25.4: + version "0.25.4" + resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.25.4.tgz#325b8a0a79fc423db109b77fd5a19183b7ba5143" + integrity sha512-oycWO9nEVAP2RVPbIoDoA4Y7LFIJ3xRYov93gAyJhZkET1tNuB0u7uWkZS2LpBWTJUWnmau/To8ECWRC+jKNfw== dependencies: sourcemap-codec "^1.4.4"