Skip to content

Webpack 5 #20084

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 9 commits into from
7 changes: 3 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@
"common-tags": "^1.8.0",
"conventional-changelog": "^3.0.0",
"conventional-commits-parser": "^3.0.0",
"copy-webpack-plugin": "6.3.2",
"copy-webpack-plugin": "8.1.1",
"core-js": "3.10.0",
"critters": "0.0.10",
"css-loader": "5.0.2",
Expand Down Expand Up @@ -199,7 +199,7 @@
"rimraf": "3.0.2",
"rxjs": "6.6.7",
"sass": "1.32.8",
"sass-loader": "10.1.1",
"sass-loader": "11.0.1",
"sauce-connect-proxy": "https://saucelabs.com/downloads/sc-4.6.4-linux.tar.gz",
"semver": "7.3.5",
"source-map": "0.7.3",
Expand All @@ -226,13 +226,12 @@
"typescript": "4.2.3",
"verdaccio": "4.12.0",
"verdaccio-auth-memory": "^10.0.0",
"webpack": "4.44.2",
"webpack": "5.30.0",
"webpack-dev-middleware": "4.1.0",
"webpack-dev-server": "3.11.2",
"webpack-merge": "5.7.3",
"webpack-sources": "2.2.0",
"webpack-subresource-integrity": "1.5.2",
"worker-plugin": "5.0.0",
"zone.js": "^0.11.3"
}
}
5 changes: 2 additions & 3 deletions packages/angular_devkit/build_angular/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,6 @@ ts_library(
"@npm//webpack-merge",
"@npm//webpack-sources",
"@npm//webpack-subresource-integrity",
"@npm//worker-plugin",
],
)

Expand Down Expand Up @@ -286,10 +285,10 @@ LARGE_SPECS = {
"tags": ["no-remote-exec"],
},
"dev-server": {
"shards": 10,
"size": "large",
"extra_deps": [
"@npm//@types/express",
"@npm//@types/node-fetch",
"@npm//express",
"@npm//node-fetch",
"@npm//@types/http-proxy",
"@npm//http-proxy",
Expand Down
9 changes: 4 additions & 5 deletions packages/angular_devkit/build_angular/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
"cacache": "15.0.6",
"caniuse-lite": "^1.0.30001032",
"circular-dependency-plugin": "5.2.2",
"copy-webpack-plugin": "6.3.2",
"copy-webpack-plugin": "8.1.1",
"core-js": "3.10.0",
"critters": "0.0.10",
"css-loader": "5.0.2",
Expand Down Expand Up @@ -58,7 +58,7 @@
"rimraf": "3.0.2",
"rxjs": "6.6.7",
"sass": "1.32.8",
"sass-loader": "10.1.1",
"sass-loader": "11.0.1",
"semver": "7.3.5",
"source-map": "0.7.3",
"source-map-loader": "1.1.3",
Expand All @@ -70,13 +70,12 @@
"terser-webpack-plugin": "4.2.3",
"text-table": "0.2.0",
"tree-kill": "1.2.2",
"webpack": "4.44.2",
"webpack": "5.30.0",
"webpack-dev-middleware": "4.1.0",
"webpack-dev-server": "3.11.2",
"webpack-merge": "5.7.3",
"webpack-sources": "2.2.0",
"webpack-subresource-integrity": "1.5.2",
"worker-plugin": "5.0.0"
"webpack-subresource-integrity": "1.5.2"
},
"peerDependencies": {
"@angular/compiler-cli": "^12.0.0-next",
Expand Down
7 changes: 4 additions & 3 deletions packages/angular_devkit/build_angular/src/browser/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ import {
BundleStats,
ChunkType,
JsonChunkStats,
JsonCompilationStats,
generateBundleStats,
statsErrorsToString,
statsHasErrors,
Expand Down Expand Up @@ -250,11 +251,11 @@ export function buildWebpackBrowser(
spinner.enabled = options.progress !== false;

const {
webpackStats: webpackRawStats,
success,
emittedFiles = [],
outputPath: webpackOutputPath,
} = buildEvent;
const webpackRawStats = buildEvent.webpackStats as JsonCompilationStats;
if (!webpackRawStats) {
throw new Error('Webpack stats build result is required.');
}
Expand Down Expand Up @@ -608,10 +609,10 @@ export function buildWebpackBrowser(
for (const { severity, message } of budgetFailures) {
switch (severity) {
case ThresholdSeverity.Warning:
webpackStats.warnings.push(message);
webpackStats.warnings?.push({message});
break;
case ThresholdSeverity.Error:
webpackStats.errors.push(message);
webpackStats.errors?.push({message});
break;
default:
assertNever(severity);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,13 @@ describe('Browser Builder deploy url', () => {
const overrides = { deployUrl: 'deployUrl/' };
const overrides2 = { deployUrl: 'http://example.com/some/path/' };

// Add lazy loaded chunk to provide a usage of the deploy URL
// Webpack 5+ will not include the deploy URL in the code unless needed
host.appendToFile('src/main.ts', '\nimport("./lazy");');
host.writeMultipleFiles({
'src/lazy.ts': 'export const foo = "bar";',
});

const run = await architect.scheduleTarget(targetSpec, overrides);
const output = await run.result as BrowserBuilderOutput;
expect(output.success).toBe(true);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,6 @@ describe('Browser Builder errors', () => {
// Wait for the builder to complete
await run.stop();

expect(logs.join()).toContain(`export 'missingExport' was not found in 'rxjs'`);
expect(logs.join()).toContain(`export 'missingExport' (imported as 'missingExport') was not found in 'rxjs'`);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ describe('Browser Builder lazy modules', () => {
host.writeMultipleFiles(lazyModuleFnImport);

const { files } = await browserBuild(architect, host, target);
expect('lazy-lazy-module.js' in files).toBe(true);
expect('src_app_lazy_lazy_module_ts.js' in files).toBe(true);
});

it('supports lazy bundle for lazy routes with AOT', async () => {
Expand All @@ -67,7 +67,7 @@ describe('Browser Builder lazy modules', () => {
addLazyLoadedModulesInTsConfig(host, lazyModuleFiles);

const { files } = await browserBuild(architect, host, target, { aot: true });
const data = await files['lazy-lazy-module.js'];
const data = await files['src_app_lazy_lazy_module_ts.js'];
expect(data).not.toBeUndefined('Lazy module output bundle does not exist');
expect(data).toContain('LazyModule.ɵmod');
});
Expand Down Expand Up @@ -128,7 +128,7 @@ describe('Browser Builder lazy modules', () => {
});

const { files } = await browserBuild(architect, host, target);
expect(files['lazy-module.js']).not.toBeUndefined();
expect(files['src_lazy-module_ts.js']).not.toBeUndefined();
});

it(`supports lazy bundle for dynamic import() calls`, async () => {
Expand All @@ -139,19 +139,11 @@ describe('Browser Builder lazy modules', () => {
import(/*webpackChunkName: '[request]'*/'./lazy-' + lazyFileName);
`,
});

const { files } = await browserBuild(architect, host, target);
expect(files['lazy-module.js']).not.toBeUndefined();
});

it(`supports lazy bundle for System.import() calls`, async () => {
const lazyfiles = {
'src/lazy-module.ts': 'export const value = 42;',
'src/main.ts': `declare var System: any; System.import('./lazy-module');`,
};

host.writeMultipleFiles(lazyfiles);
addLazyLoadedModulesInTsConfig(host, lazyfiles);
host.replaceInFile(
'src/tsconfig.app.json',
'"main.ts"',
`"main.ts","lazy-module.ts"`,
);

const { files } = await browserBuild(architect, host, target);
expect(files['lazy-module.js']).not.toBeUndefined();
Expand All @@ -165,10 +157,9 @@ describe('Browser Builder lazy modules', () => {
});

const { files } = await browserBuild(architect, host, target);
expect(files['one.js']).not.toBeUndefined();
expect(files['two.js']).not.toBeUndefined();
// TODO: the chunk with common modules used to be called `common`, see why that changed.
expect(files['default~one~two.js']).not.toBeUndefined();
expect(files['src_one_ts.js']).not.toBeUndefined();
expect(files['src_two_ts.js']).not.toBeUndefined();
expect(files['default-node_modules_angular_common___ivy_ngcc___fesm2015_http_js.js']).toBeDefined();
});

it(`supports disabling the common bundle`, async () => {
Expand All @@ -179,8 +170,8 @@ describe('Browser Builder lazy modules', () => {
});

const { files } = await browserBuild(architect, host, target, { commonChunk: false });
expect(files['one.js']).not.toBeUndefined();
expect(files['two.js']).not.toBeUndefined();
expect(files['common.js']).toBeUndefined();
expect(files['src_one_ts.js']).not.toBeUndefined();
expect(files['src_two_ts.js']).not.toBeUndefined();
expect(files['default-node_modules_angular_common___ivy_ngcc___fesm2015_http_js.js']).toBeUndefined();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ describe('Browser Builder rebuilds', () => {
debounceTime(rebuildDebounceTime),
tap(result => {
expect(result.success).toBe(true, 'build should succeed');
const hasLazyChunk = host.scopedSync().exists(normalize('dist/lazy-lazy-module.js'));
const hasLazyChunk = host.scopedSync().exists(normalize('dist/src_app_lazy_lazy_module_ts.js'));
switch (phase) {
case 1:
// No lazy chunk should exist.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,13 @@ describe('Browser Builder resolve json module', () => {

switch (buildCount) {
case 1:
expect(content).toContain('\\"foo\\":\\"1\\"');
expect(content).toContain('"foo":"1"');
host.writeMultipleFiles({
'src/my-json-file.json': `{"foo": "2"}`,
});
break;
case 2:
expect(content).toContain('\\"foo\\":\\"2\\"');
expect(content).toContain('"foo":"2"');
break;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ describe('Browser Builder Web Worker support', () => {
if (environment.production) { enableProdMode(); }
platformBrowserDynamic().bootstrapModule(AppModule).catch(err => console.error(err));

const worker = new Worker('./app/app.worker', { type: 'module' });
const worker = new Worker(new URL('./app/app.worker', import.meta.url), { type: 'module' });
worker.onmessage = ({ data }) => {
console.log('page got message:', data);
};
Expand Down Expand Up @@ -96,14 +96,14 @@ describe('Browser Builder Web Worker support', () => {

// Worker bundle contains worker code.
const workerContent = virtualFs.fileBufferToString(
host.scopedSync().read(join(outputPath, '0.worker.js')));
host.scopedSync().read(join(outputPath, 'src_app_app_worker_ts.js')));
expect(workerContent).toContain('hello from worker');
expect(workerContent).toContain('bar');

// Main bundle references worker.
const mainContent = virtualFs.fileBufferToString(
host.scopedSync().read(join(outputPath, 'main.js')));
expect(mainContent).toContain('0.worker.js');
expect(mainContent).toContain('src_app_app_worker_ts');
expect(logs.join().includes('Warning')).toBe(false, 'Should show no warnings.');
});

Expand All @@ -117,7 +117,7 @@ describe('Browser Builder Web Worker support', () => {
await browserBuild(architect, host, target, overrides);

// Worker bundle should have hash and minified code.
const workerBundle = host.fileMatchExists(outputPath, /0\.[0-9a-f]{20}\.worker\.js/) as string;
const workerBundle = host.fileMatchExists(outputPath, /src_app_app_worker_ts\.[0-9a-f]{20}\.js/) as string;
expect(workerBundle).toBeTruthy('workerBundle should exist');
const workerContent = virtualFs.fileBufferToString(
host.scopedSync().read(join(outputPath, workerBundle)));
Expand All @@ -130,7 +130,7 @@ describe('Browser Builder Web Worker support', () => {
expect(mainBundle).toBeTruthy('mainBundle should exist');
const mainContent = virtualFs.fileBufferToString(
host.scopedSync().read(join(outputPath, mainBundle)));
expect(mainContent).toContain(workerBundle);
expect(mainContent).toContain('src_app_app_worker_ts');
});

it('rebuilds TS worker', async () => {
Expand All @@ -141,7 +141,7 @@ describe('Browser Builder Web Worker support', () => {
};

let phase = 1;
const workerPath = join(outputPath, '0.worker.js');
const workerPath = join(outputPath, 'src_app_app_worker_ts.js');
let workerContent = '';

// The current linux-based CI environments may not fully settled in regards to filesystem
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ import { buildWebpackBrowser } from '../../index';
import { BASE_OPTIONS, BROWSER_BUILDER_INFO, describeBuilder } from '../setup';

const MAIN_OUTPUT = 'dist/main.js';
const NAMED_LAZY_OUTPUT = 'dist/lazy-module.js';
const UNNAMED_LAZY_OUTPUT = 'dist/0.js';
const NAMED_LAZY_OUTPUT = 'dist/src_lazy-module_ts.js';
const UNNAMED_LAZY_OUTPUT = 'dist/339.js';

describeBuilder(buildWebpackBrowser, BROWSER_BUILDER_INFO, (harness) => {
describe('Option: "namedChunks"', () => {
Expand Down
11 changes: 8 additions & 3 deletions packages/angular_devkit/build_angular/src/dev-server/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,10 @@ export function serveWebpackBrowser(
logger.warn(`Warning: 'outputHashing' option is disabled when using the dev-server.`);
}

// Webpack's live reload functionality adds the `strip-ansi` package which is commonJS
rawBrowserOptions.allowedCommonJsDependencies ??= [];
rawBrowserOptions.allowedCommonJsDependencies.push('strip-ansi');

const browserName = await context.getBuilderNameForTarget(browserTarget);
const browserOptions = await context.validateOptions(
{ ...rawBrowserOptions, ...overrides },
Expand Down Expand Up @@ -165,7 +169,8 @@ export function serveWebpackBrowser(
// This is needed because we cannot use the inline option directly in the config
// because of the SuppressExtractedTextChunksWebpackPlugin
// Consider not using SuppressExtractedTextChunksWebpackPlugin when liveReload is enable.
webpackDevServer.addDevServerEntrypoints(config, {
// tslint:disable-next-line: no-any
webpackDevServer.addDevServerEntrypoints(config as any, {
...config.devServer,
inline: true,
});
Expand All @@ -175,7 +180,7 @@ export function serveWebpackBrowser(
// 'addDevServerEntrypoints' adds addional entry-points to all entries.
if (config.entry && typeof config.entry === 'object' && !Array.isArray(config.entry) && config.entry.main) {
for (const [key, value] of Object.entries(config.entry)) {
if (key === 'main' || typeof value === 'string') {
if (key === 'main' || !Array.isArray(value)) {
continue;
}

Expand Down Expand Up @@ -362,7 +367,7 @@ async function setupLocalize(
if (Array.isArray(webpackConfig.entry['main'])) {
webpackConfig.entry['main'].unshift(localeDescription.dataPath);
} else {
webpackConfig.entry['main'] = [localeDescription.dataPath, webpackConfig.entry['main']];
webpackConfig.entry['main'] = [localeDescription.dataPath, webpackConfig.entry['main'] as string];
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ describeBuilder(serveWebpackBrowser, DEV_SERVER_BUILDER_INFO, (harness) => {
expect(result?.success).toBeTrue();
expect(result?.baseUrl).toMatch(/\/test$/);
expect(response?.url).toMatch(/\/test\/runtime.js$/);
expect(await response?.text()).toContain('window["webpackJsonp"]');
expect(await response?.text()).toContain('self["webpackChunk"]');
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ describeBuilder(serveWebpackBrowser, DEV_SERVER_BUILDER_INFO, (harness) => {
expect(result?.success).toBeTrue();
const baseUrl = new URL(`${result?.baseUrl}`);
expect(baseUrl.pathname).toBe('/');
expect(await response?.text()).toContain('window["webpackJsonp"]');
expect(await response?.text()).toContain('self["webpackChunk"]');
});

it('serves application at specified path when option is used', async () => {
Expand All @@ -48,7 +48,7 @@ describeBuilder(serveWebpackBrowser, DEV_SERVER_BUILDER_INFO, (harness) => {
expect(result?.success).toBeTrue();
const baseUrl = new URL(`${result?.baseUrl}/`);
expect(baseUrl.pathname).toBe('/test/');
expect(await response?.text()).toContain('window["webpackJsonp"]');
expect(await response?.text()).toContain('self["webpackChunk"]');
});

it('does not rewrite from root when option is used', async () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import { serveWebpackBrowser } from '../../index';
import { BASE_OPTIONS, DEV_SERVER_BUILDER_INFO, describeBuilder, setupBrowserTarget } from '../setup';

const VERBOSE_LOG_TEXT = 'Built at';
const VERBOSE_LOG_TEXT = /\[emitted\] \(name: main\)/;

describeBuilder(serveWebpackBrowser, DEV_SERVER_BUILDER_INFO, (harness) => {
describe('Option: "verbose"', () => {
Expand Down
Loading