Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 0014459

Browse filesBrowse files
clydindgp1130
authored andcommitted
fix(@angular-devkit/build-angular): account for package.json exports with Sass in esbuild builder
When using the experimental esbuild-based browser application builder, Sass module imports will now resolve using esbuild's resolve methods. This allows for package.json exports and main fields to be recognized when resolving an import or use rules in Sass files (scss or sass file extensions). (cherry picked from commit 0662a2e)
1 parent 1e29b81 commit 0014459
Copy full SHA for 0014459

File tree

Expand file treeCollapse file tree

2 files changed

+63
-8
lines changed
Filter options
Expand file treeCollapse file tree

2 files changed

+63
-8
lines changed

‎packages/angular_devkit/build_angular/src/builders/browser-esbuild/sass-plugin.ts

Copy file name to clipboardExpand all lines: packages/angular_devkit/build_angular/src/builders/browser-esbuild/sass-plugin.ts
+62-3Lines changed: 62 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,23 @@
88

99
import type { PartialMessage, Plugin, PluginBuild } from 'esbuild';
1010
import { readFile } from 'node:fs/promises';
11-
import { dirname, relative } from 'node:path';
11+
import { dirname, join, relative } from 'node:path';
1212
import { fileURLToPath, pathToFileURL } from 'node:url';
1313
import type { CompileResult, Exception } from 'sass';
14-
import { SassWorkerImplementation } from '../../sass/sass-service';
14+
import {
15+
FileImporterWithRequestContextOptions,
16+
SassWorkerImplementation,
17+
} from '../../sass/sass-service';
1518

16-
let sassWorkerPool: SassWorkerImplementation;
19+
let sassWorkerPool: SassWorkerImplementation | undefined;
1720

1821
function isSassException(error: unknown): error is Exception {
1922
return !!error && typeof error === 'object' && 'sassMessage' in error;
2023
}
2124

2225
export function shutdownSassWorkerPool(): void {
2326
sassWorkerPool?.close();
27+
sassWorkerPool = undefined;
2428
}
2529

2630
export function createSassPlugin(options: { sourcemap: boolean; loadPaths?: string[] }): Plugin {
@@ -41,6 +45,61 @@ export function createSassPlugin(options: { sourcemap: boolean; loadPaths?: stri
4145
sourceMap: options.sourcemap,
4246
sourceMapIncludeSources: options.sourcemap,
4347
quietDeps: true,
48+
importers: [
49+
{
50+
findFileUrl: async (
51+
url,
52+
{ previousResolvedModules }: FileImporterWithRequestContextOptions,
53+
): Promise<URL | null> => {
54+
let result = await build.resolve(url, {
55+
kind: 'import-rule',
56+
// This should ideally be the directory of the importer file from Sass
57+
// but that is not currently available from the Sass importer API.
58+
resolveDir: build.initialOptions.absWorkingDir,
59+
});
60+
61+
// Workaround to support Yarn PnP without access to the importer file from Sass
62+
if (!result.path && previousResolvedModules?.size) {
63+
for (const previous of previousResolvedModules) {
64+
result = await build.resolve(url, {
65+
kind: 'import-rule',
66+
resolveDir: previous,
67+
});
68+
}
69+
}
70+
71+
// Check for package deep imports
72+
if (!result.path) {
73+
const parts = url.split('/');
74+
const hasScope = parts.length > 2 && parts[0].startsWith('@');
75+
if (hasScope || parts.length > 1) {
76+
const [nameOrScope, nameOrFirstPath, ...pathPart] = parts;
77+
const packageName = hasScope
78+
? `${nameOrScope}/${nameOrFirstPath}`
79+
: nameOrScope;
80+
const packageResult = await build.resolve(packageName + '/package.json', {
81+
kind: 'import-rule',
82+
// This should ideally be the directory of the importer file from Sass
83+
// but that is not currently available from the Sass importer API.
84+
resolveDir: build.initialOptions.absWorkingDir,
85+
});
86+
87+
if (packageResult.path) {
88+
return pathToFileURL(
89+
join(
90+
dirname(packageResult.path),
91+
!hasScope ? nameOrFirstPath : '',
92+
...pathPart,
93+
),
94+
);
95+
}
96+
}
97+
}
98+
99+
return result.path ? pathToFileURL(result.path) : null;
100+
},
101+
},
102+
],
44103
logger: {
45104
warn: (text, { deprecation, span }) => {
46105
warnings.push({

‎packages/angular_devkit/build_angular/src/builders/browser-esbuild/stylesheets.ts

Copy file name to clipboardExpand all lines: packages/angular_devkit/build_angular/src/builders/browser-esbuild/stylesheets.ts
+1-5Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,6 @@ async function bundleStylesheet(
2727
entry: Required<Pick<BuildOptions, 'stdin'> | Pick<BuildOptions, 'entryPoints'>>,
2828
options: BundleStylesheetOptions,
2929
) {
30-
const loadPaths = options.includePaths ?? [];
31-
// Needed to resolve node packages.
32-
loadPaths.push(path.join(options.workspaceRoot, 'node_modules'));
33-
3430
// Execute esbuild
3531
const result = await bundle({
3632
...entry,
@@ -50,7 +46,7 @@ async function bundleStylesheet(
5046
conditions: ['style', 'sass'],
5147
mainFields: ['style', 'sass'],
5248
plugins: [
53-
createSassPlugin({ sourcemap: !!options.sourcemap, loadPaths }),
49+
createSassPlugin({ sourcemap: !!options.sourcemap, loadPaths: options.includePaths }),
5450
createCssResourcePlugin(),
5551
],
5652
});

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.