mirror of
https://github.com/angular/angular-cli.git
synced 2025-05-17 02:54:21 +08:00
refactor(@angular/build): remove Webpack-specific options from Vite-only dev-server
The `dev-server` build within the `@angular/build` package no longer uses Webpack. As a result, the Webpack related options have been removed from the builder schema. These options were not previously used by the Vite-based development server with the exception of `browserTarget` which was removed due to it being deprecated on the `@angular-devkit/build-angular` version.
This commit is contained in:
parent
0a59eae5fd
commit
c8b1fc045f
@ -110,12 +110,7 @@ export enum BuildOutputFileType {
|
||||
|
||||
// @public
|
||||
export interface DevServerBuilderOptions {
|
||||
allowedHosts?: string[];
|
||||
// @deprecated
|
||||
browserTarget?: string;
|
||||
buildTarget?: string;
|
||||
disableHostCheck?: boolean;
|
||||
forceEsbuild?: boolean;
|
||||
buildTarget: string;
|
||||
headers?: {
|
||||
[key: string]: string;
|
||||
};
|
||||
@ -127,7 +122,6 @@ export interface DevServerBuilderOptions {
|
||||
port?: number;
|
||||
prebundle?: PrebundleUnion;
|
||||
proxyConfig?: string;
|
||||
publicHost?: string;
|
||||
servePath?: string;
|
||||
ssl?: boolean;
|
||||
sslCert?: string;
|
||||
|
@ -86,8 +86,8 @@ async function initialize(
|
||||
const builderName = await context.getBuilderNameForTarget(normalizedOptions.buildTarget);
|
||||
|
||||
if (
|
||||
!normalizedOptions.disableHostCheck &&
|
||||
!/^127\.\d+\.\d+\.\d+/g.test(normalizedOptions.host) &&
|
||||
normalizedOptions.host !== '::1' &&
|
||||
normalizedOptions.host !== 'localhost'
|
||||
) {
|
||||
context.logger.warn(`
|
||||
@ -96,18 +96,10 @@ 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.
|
||||
websocket connection issues.
|
||||
`);
|
||||
}
|
||||
|
||||
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.',
|
||||
);
|
||||
}
|
||||
|
||||
normalizedOptions.port = await checkPort(normalizedOptions.port, normalizedOptions.host);
|
||||
|
||||
return {
|
||||
|
@ -35,7 +35,7 @@ export async function normalizeOptions(
|
||||
const cacheOptions = normalizeCacheOptions(projectMetadata, workspaceRoot);
|
||||
|
||||
// Target specifier defaults to the current project's build target using a development configuration
|
||||
const buildTargetSpecifier = options.buildTarget ?? options.browserTarget ?? `::development`;
|
||||
const buildTargetSpecifier = options.buildTarget ?? `::development`;
|
||||
const buildTarget = targetFromTargetString(buildTargetSpecifier, projectName, 'build');
|
||||
|
||||
// Initial options to keep
|
||||
@ -46,18 +46,14 @@ export async function normalizeOptions(
|
||||
open,
|
||||
verbose,
|
||||
watch,
|
||||
allowedHosts,
|
||||
disableHostCheck,
|
||||
liveReload,
|
||||
hmr,
|
||||
headers,
|
||||
proxyConfig,
|
||||
servePath,
|
||||
publicHost,
|
||||
ssl,
|
||||
sslCert,
|
||||
sslKey,
|
||||
forceEsbuild,
|
||||
prebundle,
|
||||
} = options;
|
||||
|
||||
@ -76,15 +72,11 @@ export async function normalizeOptions(
|
||||
workspaceRoot,
|
||||
projectRoot,
|
||||
cacheOptions,
|
||||
allowedHosts,
|
||||
disableHostCheck,
|
||||
proxyConfig,
|
||||
servePath,
|
||||
publicHost,
|
||||
ssl,
|
||||
sslCert,
|
||||
sslKey,
|
||||
forceEsbuild,
|
||||
// Prebundling defaults to true but requires caching to function
|
||||
prebundle: cacheOptions.enabled && (prebundle ?? true),
|
||||
};
|
||||
|
@ -4,12 +4,6 @@
|
||||
"description": "Dev Server target options for Build Facade.",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"browserTarget": {
|
||||
"type": "string",
|
||||
"description": "A browser builder target to serve in the format of `project:target[:configuration]`. You can also pass in more than one configuration name as a comma-separated list. Example: `project:target:production,staging`.",
|
||||
"pattern": "^[^:\\s]+:[^:\\s]+(:[^\\s]+)?$",
|
||||
"x-deprecated": "Use 'buildTarget' instead."
|
||||
},
|
||||
"buildTarget": {
|
||||
"type": "string",
|
||||
"description": "A build builder target to serve in the format of `project:target[:configuration]`. You can also pass in more than one configuration name as a comma-separated list. Example: `project:target:production,staging`.",
|
||||
@ -67,27 +61,10 @@
|
||||
"description": "Whether to reload the page on change, using live-reload.",
|
||||
"default": true
|
||||
},
|
||||
"publicHost": {
|
||||
"type": "string",
|
||||
"description": "The URL that the browser client (or live-reload client, if enabled) should use to connect to the development server. Use for a complex dev server setup, such as one with reverse proxies. This option has no effect when using the 'application' or other esbuild-based builders."
|
||||
},
|
||||
"allowedHosts": {
|
||||
"type": "array",
|
||||
"description": "List of hosts that are allowed to access the dev server. This option has no effect when using the 'application' or other esbuild-based builders.",
|
||||
"default": [],
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"servePath": {
|
||||
"type": "string",
|
||||
"description": "The pathname where the application will be served."
|
||||
},
|
||||
"disableHostCheck": {
|
||||
"type": "boolean",
|
||||
"description": "Don't verify connected clients are part of allowed hosts. This option has no effect when using the 'application' or other esbuild-based builders.",
|
||||
"default": false
|
||||
},
|
||||
"hmr": {
|
||||
"type": "boolean",
|
||||
"description": "Enable hot module replacement.",
|
||||
@ -102,13 +79,8 @@
|
||||
"type": "number",
|
||||
"description": "Enable and define the file watching poll time period in milliseconds."
|
||||
},
|
||||
"forceEsbuild": {
|
||||
"type": "boolean",
|
||||
"description": "Force the development server to use the 'browser-esbuild' builder when building. This is a developer preview option for the esbuild-based build system.",
|
||||
"default": false
|
||||
},
|
||||
"prebundle": {
|
||||
"description": "Enable and control the Vite-based development server's prebundling capabilities. To enable prebundling, the Angular CLI cache must also be enabled. This option has no effect when using the 'browser' or other Webpack-based builders.",
|
||||
"description": "Enable and control the Vite-based development server's prebundling capabilities. To enable prebundling, the Angular CLI cache must also be enabled.",
|
||||
"oneOf": [
|
||||
{ "type": "boolean" },
|
||||
{
|
||||
@ -127,5 +99,5 @@
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"anyOf": [{ "required": ["buildTarget"] }, { "required": ["browserTarget"] }]
|
||||
"required": ["buildTarget"]
|
||||
}
|
||||
|
@ -1,71 +0,0 @@
|
||||
/**
|
||||
* @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 { executeDevServer } from '../../index';
|
||||
import { executeOnceAndFetch } from '../execute-fetch';
|
||||
import { describeServeBuilder } from '../jasmine-helpers';
|
||||
import { BASE_OPTIONS, DEV_SERVER_BUILDER_INFO } from '../setup';
|
||||
|
||||
const FETCH_HEADERS = Object.freeze({ host: 'example.com' });
|
||||
|
||||
describeServeBuilder(
|
||||
executeDevServer,
|
||||
DEV_SERVER_BUILDER_INFO,
|
||||
(harness, setupTarget, isViteRun) => {
|
||||
// TODO(fix-vite): currently this is broken in vite.
|
||||
(isViteRun ? xdescribe : xdescribe)('option: "allowedHosts"', () => {
|
||||
beforeEach(async () => {
|
||||
setupTarget(harness);
|
||||
|
||||
// Application code is not needed for these tests
|
||||
await harness.writeFile('src/main.ts', '');
|
||||
});
|
||||
|
||||
it('does not allow an invalid host when option is not present', async () => {
|
||||
harness.useTarget('serve', {
|
||||
...BASE_OPTIONS,
|
||||
});
|
||||
|
||||
const { result, response } = await executeOnceAndFetch(harness, '/', {
|
||||
request: { headers: FETCH_HEADERS },
|
||||
});
|
||||
|
||||
expect(result?.success).toBeTrue();
|
||||
expect(await response?.text()).toBe('Invalid Host header');
|
||||
});
|
||||
|
||||
it('does not allow an invalid host when option is an empty array', async () => {
|
||||
harness.useTarget('serve', {
|
||||
...BASE_OPTIONS,
|
||||
allowedHosts: [],
|
||||
});
|
||||
|
||||
const { result, response } = await executeOnceAndFetch(harness, '/', {
|
||||
request: { headers: FETCH_HEADERS },
|
||||
});
|
||||
|
||||
expect(result?.success).toBeTrue();
|
||||
expect(await response?.text()).toBe('Invalid Host header');
|
||||
});
|
||||
|
||||
it('allows a host when specified in the option', async () => {
|
||||
harness.useTarget('serve', {
|
||||
...BASE_OPTIONS,
|
||||
allowedHosts: ['example.com'],
|
||||
});
|
||||
|
||||
const { result, response } = await executeOnceAndFetch(harness, '/', {
|
||||
request: { headers: FETCH_HEADERS },
|
||||
});
|
||||
|
||||
expect(result?.success).toBeTrue();
|
||||
expect(await response?.text()).toContain('<title>');
|
||||
});
|
||||
});
|
||||
},
|
||||
);
|
@ -1,71 +0,0 @@
|
||||
/**
|
||||
* @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 { executeDevServer } from '../../index';
|
||||
import { executeOnceAndFetch } from '../execute-fetch';
|
||||
import { describeServeBuilder } from '../jasmine-helpers';
|
||||
import { BASE_OPTIONS, DEV_SERVER_BUILDER_INFO } from '../setup';
|
||||
|
||||
const FETCH_HEADERS = Object.freeze({ host: 'example.com' });
|
||||
|
||||
describeServeBuilder(
|
||||
executeDevServer,
|
||||
DEV_SERVER_BUILDER_INFO,
|
||||
(harness, setupTarget, isViteRun) => {
|
||||
// This option is not used when using vite.
|
||||
(isViteRun ? xdescribe : xdescribe)('option: "disableHostCheck"', () => {
|
||||
beforeEach(async () => {
|
||||
setupTarget(harness);
|
||||
|
||||
// Application code is not needed for these tests
|
||||
await harness.writeFile('src/main.ts', '');
|
||||
});
|
||||
|
||||
it('does not allow an invalid host when option is not present', async () => {
|
||||
harness.useTarget('serve', {
|
||||
...BASE_OPTIONS,
|
||||
});
|
||||
|
||||
const { result, response } = await executeOnceAndFetch(harness, '/', {
|
||||
request: { headers: FETCH_HEADERS },
|
||||
});
|
||||
|
||||
expect(result?.success).toBeTrue();
|
||||
expect(await response?.text()).toBe('Invalid Host header');
|
||||
});
|
||||
|
||||
it('does not allow an invalid host when option is false', async () => {
|
||||
harness.useTarget('serve', {
|
||||
...BASE_OPTIONS,
|
||||
disableHostCheck: false,
|
||||
});
|
||||
|
||||
const { result, response } = await executeOnceAndFetch(harness, '/', {
|
||||
request: { headers: FETCH_HEADERS },
|
||||
});
|
||||
|
||||
expect(result?.success).toBeTrue();
|
||||
expect(await response?.text()).toBe('Invalid Host header');
|
||||
});
|
||||
|
||||
it('allows a host when option is true', async () => {
|
||||
harness.useTarget('serve', {
|
||||
...BASE_OPTIONS,
|
||||
disableHostCheck: true,
|
||||
});
|
||||
|
||||
const { result, response } = await executeOnceAndFetch(harness, '/', {
|
||||
request: { headers: FETCH_HEADERS },
|
||||
});
|
||||
|
||||
expect(result?.success).toBeTrue();
|
||||
expect(await response?.text()).toContain('<title>');
|
||||
});
|
||||
});
|
||||
},
|
||||
);
|
@ -1,79 +0,0 @@
|
||||
/**
|
||||
* @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 { executeDevServer } from '../../index';
|
||||
import { executeOnceAndFetch } from '../execute-fetch';
|
||||
import { describeServeBuilder } from '../jasmine-helpers';
|
||||
import { BASE_OPTIONS, DEV_SERVER_BUILDER_INFO } from '../setup';
|
||||
|
||||
const ESBUILD_LOG_TEXT = 'Application bundle generation complete.';
|
||||
const WEBPACK_LOG_TEXT = 'Compiled successfully.';
|
||||
|
||||
describeServeBuilder(
|
||||
executeDevServer,
|
||||
DEV_SERVER_BUILDER_INFO,
|
||||
(harness, setupTarget, isViteRun) => {
|
||||
describe('option: "forceEsbuild"', () => {
|
||||
beforeEach(async () => {
|
||||
setupTarget(harness, {});
|
||||
|
||||
// Application code is not needed for these tests
|
||||
await harness.writeFile('src/main.ts', 'console.log("foo");');
|
||||
});
|
||||
|
||||
it('should use build target specified build system when not present', async () => {
|
||||
harness.useTarget('serve', {
|
||||
...BASE_OPTIONS,
|
||||
forceEsbuild: undefined,
|
||||
});
|
||||
|
||||
const { result, response, logs } = await executeOnceAndFetch(harness, '/main.js');
|
||||
|
||||
expect(result?.success).toBeTrue();
|
||||
expect(await response?.text()).toContain('console.log');
|
||||
expect(logs).toContain(
|
||||
jasmine.objectContaining({
|
||||
message: jasmine.stringMatching(isViteRun ? ESBUILD_LOG_TEXT : WEBPACK_LOG_TEXT),
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
it('should use build target specified build system when false', async () => {
|
||||
harness.useTarget('serve', {
|
||||
...BASE_OPTIONS,
|
||||
forceEsbuild: false,
|
||||
});
|
||||
|
||||
const { result, response, logs } = await executeOnceAndFetch(harness, '/main.js');
|
||||
|
||||
expect(result?.success).toBeTrue();
|
||||
expect(await response?.text()).toContain('console.log');
|
||||
expect(logs).toContain(
|
||||
jasmine.objectContaining({
|
||||
message: jasmine.stringMatching(isViteRun ? ESBUILD_LOG_TEXT : WEBPACK_LOG_TEXT),
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
it('should always use the esbuild build system with Vite when true', async () => {
|
||||
harness.useTarget('serve', {
|
||||
...BASE_OPTIONS,
|
||||
forceEsbuild: true,
|
||||
});
|
||||
|
||||
const { result, response, logs } = await executeOnceAndFetch(harness, '/main.js');
|
||||
|
||||
expect(result?.success).toBeTrue();
|
||||
expect(await response?.text()).toContain('console.log');
|
||||
expect(logs).toContain(
|
||||
jasmine.objectContaining({ message: jasmine.stringMatching(ESBUILD_LOG_TEXT) }),
|
||||
);
|
||||
});
|
||||
});
|
||||
},
|
||||
);
|
@ -1,71 +0,0 @@
|
||||
/**
|
||||
* @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 { executeDevServer } from '../../index';
|
||||
import { executeOnceAndFetch } from '../execute-fetch';
|
||||
import { describeServeBuilder } from '../jasmine-helpers';
|
||||
import { BASE_OPTIONS, DEV_SERVER_BUILDER_INFO } from '../setup';
|
||||
|
||||
const FETCH_HEADERS = Object.freeze({ host: 'example.com' });
|
||||
|
||||
describeServeBuilder(
|
||||
executeDevServer,
|
||||
DEV_SERVER_BUILDER_INFO,
|
||||
(harness, setupTarget, isViteRun) => {
|
||||
// This option is not used when using vite.
|
||||
(isViteRun ? xdescribe : xdescribe)('option: "publicHost"', () => {
|
||||
beforeEach(async () => {
|
||||
setupTarget(harness);
|
||||
|
||||
// Application code is not needed for these tests
|
||||
await harness.writeFile('src/main.ts', '');
|
||||
});
|
||||
|
||||
it('does not allow an invalid host when option is not present', async () => {
|
||||
harness.useTarget('serve', {
|
||||
...BASE_OPTIONS,
|
||||
});
|
||||
|
||||
const { result, response } = await executeOnceAndFetch(harness, '/', {
|
||||
request: { headers: FETCH_HEADERS },
|
||||
});
|
||||
|
||||
expect(result?.success).toBeTrue();
|
||||
expect(await response?.text()).toBe('Invalid Host header');
|
||||
});
|
||||
|
||||
it('does not allow an invalid host when option is a different host', async () => {
|
||||
harness.useTarget('serve', {
|
||||
...BASE_OPTIONS,
|
||||
publicHost: 'example.net',
|
||||
});
|
||||
|
||||
const { result, response } = await executeOnceAndFetch(harness, '/', {
|
||||
request: { headers: FETCH_HEADERS },
|
||||
});
|
||||
|
||||
expect(result?.success).toBeTrue();
|
||||
expect(await response?.text()).toBe('Invalid Host header');
|
||||
});
|
||||
|
||||
it('allows a host when option is set to used host', async () => {
|
||||
harness.useTarget('serve', {
|
||||
...BASE_OPTIONS,
|
||||
publicHost: 'example.com',
|
||||
});
|
||||
|
||||
const { result, response } = await executeOnceAndFetch(harness, '/', {
|
||||
request: { headers: FETCH_HEADERS },
|
||||
});
|
||||
|
||||
expect(result?.success).toBeTrue();
|
||||
expect(await response?.text()).toContain('<title>');
|
||||
});
|
||||
});
|
||||
},
|
||||
);
|
Loading…
x
Reference in New Issue
Block a user