diff --git a/packages/angular_devkit/build_angular/src/browser/specs/styles_spec.ts b/packages/angular_devkit/build_angular/src/browser/specs/styles_spec.ts index 9c60146ff913..7da64970b00e 100644 --- a/packages/angular_devkit/build_angular/src/browser/specs/styles_spec.ts +++ b/packages/angular_devkit/build_angular/src/browser/specs/styles_spec.ts @@ -570,7 +570,7 @@ describe('Browser Builder styles', () => { expect(main).toContain(`url('/base/assets/component-img-absolute.svg')`); }, 90000); - it(`supports bootstrap@4`, async () => { + it(`supports bootstrap@4 with full path`, async () => { const bootstrapPath = dirname(require.resolve('bootstrap/package.json')); const overrides = { @@ -582,6 +582,16 @@ describe('Browser Builder styles', () => { await browserBuild(architect, host, target, overrides); }); + it(`supports bootstrap@4 with package reference`, async () => { + const overrides = { + extractCss: true, + styles: ['bootstrap/dist/css/bootstrap.css'], + scripts: ['bootstrap/dist/js/bootstrap.js'], + }; + + await browserBuild(architect, host, target, overrides); + }); + it(`supports inline javascript in less`, async () => { const overrides = { styles: [`src/styles.less`] }; host.writeMultipleFiles({ diff --git a/packages/angular_devkit/build_angular/src/dev-server/index.ts b/packages/angular_devkit/build_angular/src/dev-server/index.ts index 20be5820390c..2fdda29dad34 100644 --- a/packages/angular_devkit/build_angular/src/dev-server/index.ts +++ b/packages/angular_devkit/build_angular/src/dev-server/index.ts @@ -569,7 +569,16 @@ function _addLiveReload( // When HMR is enabled we need to add the css paths as part of the entrypoints // because otherwise no JS bundle will contain the HMR accept code. const normalizedStyles = normalizeExtraEntryPoints(browserOptions.styles, 'styles') - .map(style => path.resolve(root, style.input)); + .map(style => { + let resolvedPath = path.resolve(root, style.input); + if (!existsSync(resolvedPath)) { + try { + resolvedPath = require.resolve(style.input, { paths: [root] }); + } catch {} + } + + return resolvedPath; + }); entryPoints.push(...normalizedStyles); } diff --git a/packages/angular_devkit/build_angular/src/webpack/configs/common.ts b/packages/angular_devkit/build_angular/src/webpack/configs/common.ts index 57898cfc8919..de87acfc1f80 100644 --- a/packages/angular_devkit/build_angular/src/webpack/configs/common.ts +++ b/packages/angular_devkit/build_angular/src/webpack/configs/common.ts @@ -208,10 +208,14 @@ export function getCommonConfig(wco: WebpackConfigOptions): Configuration { 'scripts', ).reduce((prev: { bundleName: string; paths: string[]; inject: boolean }[], curr) => { const { bundleName, inject, input } = curr; - const resolvedPath = path.resolve(root, input); + let resolvedPath = path.resolve(root, input); if (!existsSync(resolvedPath)) { - throw new Error(`Script file ${input} does not exist.`); + try { + resolvedPath = require.resolve(input, { paths: [root] }); + } catch { + throw new Error(`Script file ${input} does not exist.`); + } } const existingEntry = prev.find(el => el.bundleName === bundleName); diff --git a/packages/angular_devkit/build_angular/src/webpack/configs/styles.ts b/packages/angular_devkit/build_angular/src/webpack/configs/styles.ts index dd6bdfab2878..74bde097204f 100644 --- a/packages/angular_devkit/build_angular/src/webpack/configs/styles.ts +++ b/packages/angular_devkit/build_angular/src/webpack/configs/styles.ts @@ -7,6 +7,7 @@ */ import { tags } from '@angular-devkit/core'; +import * as fs from 'fs'; import * as path from 'path'; import * as webpack from 'webpack'; import { WebpackConfigOptions } from '../../utils/build-options'; @@ -58,7 +59,12 @@ export function getStylesConfig(wco: WebpackConfigOptions) { const chunkNames: string[] = []; normalizeExtraEntryPoints(buildOptions.styles, 'styles').forEach(style => { - const resolvedPath = path.resolve(root, style.input); + let resolvedPath = path.resolve(root, style.input); + if (!fs.existsSync(resolvedPath)) { + try { + resolvedPath = require.resolve(style.input, { paths: [root] }); + } catch {} + } // Add style entry points. if (entryPoints[style.bundleName]) { entryPoints[style.bundleName].push(resolvedPath);