-
Notifications
You must be signed in to change notification settings - Fork 12k
/
Copy pathbuilder.ts
112 lines (99 loc) · 4.24 KB
/
builder.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* 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 type { BuilderContext } from '@angular-devkit/architect';
import { EMPTY, Observable, defer, switchMap } from 'rxjs';
import type { ExecutionTransformer } from '../../transforms';
import { checkPort } from '../../utils/check-port';
import type { IndexHtmlTransform } from '../../utils/index-file/index-html-generator';
import { purgeStaleBuildCache } from '../../utils/purge-cache';
import { normalizeOptions } from './options';
import type { Schema as DevServerBuilderOptions } from './schema';
import type { DevServerBuilderOutput } from './webpack-server';
/**
* A Builder that executes a development server based on the provided browser target option.
* @param options Dev Server options.
* @param context The build context.
* @param transforms A map of transforms that can be used to hook into some logic (such as
* transforming webpack configuration before passing it to webpack).
*
* @experimental Direct usage of this function is considered experimental.
*/
export function execute(
options: DevServerBuilderOptions,
context: BuilderContext,
transforms: {
webpackConfiguration?: ExecutionTransformer<import('webpack').Configuration>;
logging?: import('@angular-devkit/build-webpack').WebpackLoggingCallback;
indexHtml?: IndexHtmlTransform;
} = {},
): Observable<DevServerBuilderOutput> {
// Determine project name from builder context target
const projectName = context.target?.project;
if (!projectName) {
context.logger.error(`The 'dev-server' builder requires a target to be specified.`);
return EMPTY;
}
return defer(() => initialize(options, projectName, context)).pipe(
switchMap(({ builderName, normalizedOptions }) => {
// Use vite-based development server for esbuild-based builds
if (
builderName === '@angular-devkit/build-angular:application' ||
builderName === '@angular-devkit/build-angular:browser-esbuild' ||
normalizedOptions.forceEsbuild
) {
return defer(() => import('./vite-server')).pipe(
switchMap(({ serveWithVite }) => serveWithVite(normalizedOptions, builderName, context)),
);
}
// Use Webpack for all other browser targets
return defer(() => import('./webpack-server')).pipe(
switchMap(({ serveWebpackBrowser }) =>
serveWebpackBrowser(normalizedOptions, builderName, context, transforms),
),
);
}),
);
}
async function initialize(
initialOptions: DevServerBuilderOptions,
projectName: string,
context: BuilderContext,
) {
// Purge old build disk cache.
await purgeStaleBuildCache(context);
const normalizedOptions = await normalizeOptions(context, projectName, initialOptions);
const builderName = await context.getBuilderNameForTarget(normalizedOptions.buildTarget);
if (
!normalizedOptions.disableHostCheck &&
!/^127\.\d+\.\d+\.\d+/g.test(normalizedOptions.host) &&
normalizedOptions.host !== 'localhost'
) {
context.logger.warn(`
Warning: This is a simple server for use in testing or debugging Angular applications
locally. It hasn't been reviewed for security issues.
Binding this server to an open connection can result in compromising your application or
computer. Using a different host than the one passed to the "--host" flag might result in
websocket connection issues. You might need to use "--disable-host-check" if that's the
case.
`);
}
if (normalizedOptions.disableHostCheck) {
context.logger.warn(
'Warning: Running a server with --disable-host-check is a security risk. ' +
'See https://medium.com/webpack/webpack-dev-server-middleware-security-issues-1489d950874a for more information.',
);
}
if (normalizedOptions.forceEsbuild && !builderName.startsWith('@angular-devkit/build-angular:')) {
context.logger.warn(
'Warning: Forcing the use of the esbuild-based build system with third-party builders' +
' may cause unexpected behavior and/or build failures.',
);
}
normalizedOptions.port = await checkPort(normalizedOptions.port, normalizedOptions.host);
return { builderName, normalizedOptions };
}