Skip to content

Commit 0c112e5

Browse files
clydinalan-agius4
authored andcommitted
feat(@angular-devkit/build-angular): support package references in styles & scripts options
The browser builder's `styles` and `scripts` options now support using a package name in the path when specifying a style or script. This removes the need to use a relative path to the node modules directory in these options. This provides support for Yarn PnP as well as reducing the complexity of the options especially for monorepo setups. Relatively located files will take precedence over packages if they exist. This precedence provides backwards compatibility with existing configurations. Before : `"styles": ["../node_modules/bootstrap/dist/css/bootstrap.css"]` After: `"styles": ["bootstrap/dist/css/bootstrap.css"]`
1 parent dbdd3fc commit 0c112e5

File tree

4 files changed

+34
-5
lines changed

4 files changed

+34
-5
lines changed

packages/angular_devkit/build_angular/src/browser/specs/styles_spec.ts

+11-1
Original file line numberDiff line numberDiff line change
@@ -570,7 +570,7 @@ describe('Browser Builder styles', () => {
570570
expect(main).toContain(`url('/base/assets/component-img-absolute.svg')`);
571571
}, 90000);
572572

573-
it(`supports bootstrap@4`, async () => {
573+
it(`supports bootstrap@4 with full path`, async () => {
574574
const bootstrapPath = dirname(require.resolve('bootstrap/package.json'));
575575

576576
const overrides = {
@@ -582,6 +582,16 @@ describe('Browser Builder styles', () => {
582582
await browserBuild(architect, host, target, overrides);
583583
});
584584

585+
it(`supports bootstrap@4 with package reference`, async () => {
586+
const overrides = {
587+
extractCss: true,
588+
styles: ['bootstrap/dist/css/bootstrap.css'],
589+
scripts: ['bootstrap/dist/js/bootstrap.js'],
590+
};
591+
592+
await browserBuild(architect, host, target, overrides);
593+
});
594+
585595
it(`supports inline javascript in less`, async () => {
586596
const overrides = { styles: [`src/styles.less`] };
587597
host.writeMultipleFiles({

packages/angular_devkit/build_angular/src/dev-server/index.ts

+10-1
Original file line numberDiff line numberDiff line change
@@ -569,7 +569,16 @@ function _addLiveReload(
569569
// When HMR is enabled we need to add the css paths as part of the entrypoints
570570
// because otherwise no JS bundle will contain the HMR accept code.
571571
const normalizedStyles = normalizeExtraEntryPoints(browserOptions.styles, 'styles')
572-
.map(style => path.resolve(root, style.input));
572+
.map(style => {
573+
let resolvedPath = path.resolve(root, style.input);
574+
if (!existsSync(resolvedPath)) {
575+
try {
576+
resolvedPath = require.resolve(style.input, { paths: [root] });
577+
} catch {}
578+
}
579+
580+
return resolvedPath;
581+
});
573582
entryPoints.push(...normalizedStyles);
574583
}
575584

packages/angular_devkit/build_angular/src/webpack/configs/common.ts

+6-2
Original file line numberDiff line numberDiff line change
@@ -208,10 +208,14 @@ export function getCommonConfig(wco: WebpackConfigOptions): Configuration {
208208
'scripts',
209209
).reduce((prev: { bundleName: string; paths: string[]; inject: boolean }[], curr) => {
210210
const { bundleName, inject, input } = curr;
211-
const resolvedPath = path.resolve(root, input);
211+
let resolvedPath = path.resolve(root, input);
212212

213213
if (!existsSync(resolvedPath)) {
214-
throw new Error(`Script file ${input} does not exist.`);
214+
try {
215+
resolvedPath = require.resolve(input, { paths: [root] });
216+
} catch {
217+
throw new Error(`Script file ${input} does not exist.`);
218+
}
215219
}
216220

217221
const existingEntry = prev.find(el => el.bundleName === bundleName);

packages/angular_devkit/build_angular/src/webpack/configs/styles.ts

+7-1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
*/
88

99
import { tags } from '@angular-devkit/core';
10+
import * as fs from 'fs';
1011
import * as path from 'path';
1112
import * as webpack from 'webpack';
1213
import { WebpackConfigOptions } from '../../utils/build-options';
@@ -58,7 +59,12 @@ export function getStylesConfig(wco: WebpackConfigOptions) {
5859
const chunkNames: string[] = [];
5960

6061
normalizeExtraEntryPoints(buildOptions.styles, 'styles').forEach(style => {
61-
const resolvedPath = path.resolve(root, style.input);
62+
let resolvedPath = path.resolve(root, style.input);
63+
if (!fs.existsSync(resolvedPath)) {
64+
try {
65+
resolvedPath = require.resolve(style.input, { paths: [root] });
66+
} catch {}
67+
}
6268
// Add style entry points.
6369
if (entryPoints[style.bundleName]) {
6470
entryPoints[style.bundleName].push(resolvedPath);

0 commit comments

Comments
 (0)