|
1 |
| -import { BuilderContext, BuilderOutput, createBuilder, targetFromTargetString } from '@angular-devkit/architect'; |
| 1 | +import { |
| 2 | + BuilderContext, |
| 3 | + createBuilder, |
| 4 | + targetFromTargetString |
| 5 | +} from '@angular-devkit/architect'; |
| 6 | +import { |
| 7 | + ExecutionTransformer, |
| 8 | + executeDevServerBuilder |
| 9 | +} from '@angular-devkit/build-angular'; |
| 10 | +import { ScriptsWebpackPlugin } from '@angular-devkit/build-angular/src/angular-cli-files/plugins/scripts-webpack-plugin'; |
| 11 | +import { IndexHtmlTransform } from '@angular-devkit/build-angular/src/angular-cli-files/utilities/index-file/write-index-html'; |
| 12 | +import { |
| 13 | + DevServerBuilderOptions, |
| 14 | + DevServerBuilderOutput |
| 15 | +} from '@angular-devkit/build-angular/src/dev-server'; |
2 | 16 | import { json } from '@angular-devkit/core';
|
| 17 | +import * as CopyWebpackPlugin from 'copy-webpack-plugin'; |
| 18 | +import { basename } from 'path'; |
| 19 | +import { Observable, from } from 'rxjs'; |
| 20 | +import { switchMap } from 'rxjs/operators'; |
| 21 | +import { Configuration } from 'webpack'; |
3 | 22 |
|
4 |
| -import { prepareBrowserConfig } from '../utils'; |
| 23 | +import { FormattedAssets, prepareServerConfig } from '../utils'; |
| 24 | +import { augmentIndexHtml } from '../utils/append-scripts'; |
5 | 25 |
|
6 | 26 | import { createConsoleLogServer } from './log-server';
|
7 | 27 | import { CordovaServeBuilderSchema } from './schema';
|
8 | 28 |
|
9 |
| -export type CordovaDevServerBuilderOptions = CordovaServeBuilderSchema & json.JsonObject; |
| 29 | +export type CordovaDevServerBuilderOptions = CordovaServeBuilderSchema & |
| 30 | + json.JsonObject; |
10 | 31 |
|
11 |
| -export async function serveCordova( |
| 32 | +export function serveCordova( |
12 | 33 | options: CordovaServeBuilderSchema,
|
13 | 34 | context: BuilderContext
|
14 |
| -): Promise<BuilderOutput> { |
15 |
| - return new Promise(async () => { |
16 |
| - context.reportStatus(`running cordova serve...`); |
17 |
| - const { devServerTarget, cordovaBuildTarget, port, host, ssl } = options; |
| 35 | +): Observable<DevServerBuilderOutput> { |
| 36 | + const { devServerTarget, port, host, ssl } = options; |
| 37 | + const root = context.workspaceRoot; |
| 38 | + const devServerTargetSpec = targetFromTargetString(devServerTarget); |
18 | 39 |
|
19 |
| - // Getting the original browser build options |
20 |
| - const cordovaBuildTargetSpec = targetFromTargetString(cordovaBuildTarget); |
21 |
| - const cordovaBuildTargetOptions = await context.getTargetOptions(cordovaBuildTargetSpec) as { browserTarget: string }; |
22 |
| - const browserBuildTargetSpec = targetFromTargetString(cordovaBuildTargetOptions.browserTarget); |
23 |
| - |
24 |
| - // What we actually need.... |
25 |
| - const browserBuildTargetOptions = await context.getTargetOptions(browserBuildTargetSpec); |
26 |
| - |
27 |
| - // Modifying those options to pass in cordova-speicfic stuff |
28 |
| - prepareBrowserConfig(options, browserBuildTargetOptions); |
| 40 | + async function setup() { |
| 41 | + const devServerTargetOptions = (await context.getTargetOptions(devServerTargetSpec)) as DevServerBuilderOptions; |
| 42 | + const devServerName = await context.getBuilderNameForTarget(devServerTargetSpec); |
29 | 43 |
|
| 44 | + devServerTargetOptions.port = port; |
| 45 | + devServerTargetOptions.host = host; |
| 46 | + devServerTargetOptions.ssl = ssl; |
| 47 | + // tslint:disable-next-line: no-unnecessary-type-assertion |
| 48 | + const formattedOptions = await context.validateOptions(devServerTargetOptions, devServerName) as DevServerBuilderOptions; |
| 49 | + const formattedAssets = prepareServerConfig(options, root); |
30 | 50 | if (options.consolelogs && options.consolelogsPort) {
|
31 | 51 | await createConsoleLogServer(host, options.consolelogsPort);
|
32 | 52 | }
|
| 53 | + return { formattedOptions, formattedAssets }; |
| 54 | + } |
33 | 55 |
|
34 |
| - const devServerTargetSpec = targetFromTargetString(devServerTarget); |
35 |
| - const devServerTargetOptions = await context.getTargetOptions(devServerTargetSpec); |
36 |
| - |
37 |
| - return context |
38 |
| - .scheduleTarget(devServerTargetSpec, { host, port, ssl }, devServerTargetOptions) |
39 |
| - .then(buildEvent => ({ ...buildEvent })); |
40 |
| - }); |
| 56 | + return from(setup()).pipe( |
| 57 | + switchMap(({ formattedOptions, formattedAssets }) => |
| 58 | + executeDevServerBuilder( |
| 59 | + formattedOptions, |
| 60 | + context, |
| 61 | + getTransforms(formattedAssets, context) |
| 62 | + ) |
| 63 | + ) |
| 64 | + ); |
41 | 65 | }
|
42 | 66 | export default createBuilder<CordovaDevServerBuilderOptions, any>(serveCordova);
|
| 67 | + |
| 68 | +function getTransforms(formattedAssets: FormattedAssets, context: BuilderContext) { |
| 69 | + return { |
| 70 | + webpackConfiguration: cordovaServeTransform(formattedAssets, context), |
| 71 | + indexHtml: indexHtmlTransformFactory(formattedAssets, context), |
| 72 | + }; |
| 73 | +} |
| 74 | + |
| 75 | +const cordovaServeTransform: ( |
| 76 | + formattedAssets: FormattedAssets, |
| 77 | + context: BuilderContext |
| 78 | +) => ExecutionTransformer<Configuration> = ( |
| 79 | + formattedAssets, |
| 80 | + { workspaceRoot } |
| 81 | +) => browserWebpackConfig => { |
| 82 | + const scriptExtras = formattedAssets.globalScriptsByBundleName.map( |
| 83 | + (script: { bundleName: any; paths: any }) => { |
| 84 | + const bundleName = script.bundleName; |
| 85 | + return new ScriptsWebpackPlugin({ |
| 86 | + name: bundleName, |
| 87 | + sourceMap: true, |
| 88 | + filename: `${basename(bundleName)}.js`, |
| 89 | + scripts: script.paths, |
| 90 | + basePath: workspaceRoot, |
| 91 | + }); |
| 92 | + } |
| 93 | + ); |
| 94 | + |
| 95 | + const copyWebpackPluginOptions = { |
| 96 | + ignore: ['.gitkeep', '**/.DS_Store', '**/Thumbs.db'], |
| 97 | + }; |
| 98 | + const copyWebpackPluginInstance = new CopyWebpackPlugin( |
| 99 | + formattedAssets.copyWebpackPluginPatterns, |
| 100 | + copyWebpackPluginOptions |
| 101 | + ); |
| 102 | + // tslint:disable-next-line: no-non-null-assertion |
| 103 | + browserWebpackConfig.plugins!.push( |
| 104 | + ...scriptExtras, |
| 105 | + copyWebpackPluginInstance |
| 106 | + ); |
| 107 | + return browserWebpackConfig; |
| 108 | +}; |
| 109 | + |
| 110 | +export const indexHtmlTransformFactory: ( |
| 111 | + formattedAssets: FormattedAssets, |
| 112 | + context: BuilderContext |
| 113 | +) => IndexHtmlTransform = ({ globalScriptsByBundleName }) => ( |
| 114 | + indexTransform: string |
| 115 | +) => { |
| 116 | + const augmentedHtml = augmentIndexHtml( |
| 117 | + indexTransform, |
| 118 | + globalScriptsByBundleName |
| 119 | + ); |
| 120 | + return Promise.resolve(augmentedHtml); |
| 121 | +}; |
0 commit comments