Skip to content

Commit 758b069

Browse files
alan-agius4angular-robot[bot]
authored andcommitted
fix(@angular-devkit/build-angular): update list of known tailwind configuration files
With this change we added `tailwind.config.mjs` and `tailwind.config.ts` to known tailwind config files. Closes #24943
1 parent d5fed32 commit 758b069

File tree

3 files changed

+49
-47
lines changed

3 files changed

+49
-47
lines changed

packages/angular_devkit/build_angular/src/builders/browser-esbuild/options.ts

Lines changed: 2 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import path from 'node:path';
1313
import { normalizeAssetPatterns, normalizeOptimization, normalizeSourceMaps } from '../../utils';
1414
import { normalizeCacheOptions } from '../../utils/normalize-cache';
1515
import { generateEntryPoints } from '../../utils/package-chunk-sort';
16+
import { findTailwindConfigurationFile } from '../../utils/tailwind';
1617
import { getIndexInputFile, getIndexOutputFile } from '../../utils/webpack-browser-config';
1718
import { globalScriptsByBundleName, normalizeGlobalStyles } from '../../webpack/utils/helpers';
1819
import { Schema as BrowserBuilderOptions, OutputHashing } from './schema';
@@ -97,7 +98,7 @@ export async function normalizeOptions(
9798
}
9899

99100
let tailwindConfiguration: { file: string; package: string } | undefined;
100-
const tailwindConfigurationPath = findTailwindConfigurationFile(workspaceRoot, projectRoot);
101+
const tailwindConfigurationPath = await findTailwindConfigurationFile(workspaceRoot, projectRoot);
101102
if (tailwindConfigurationPath) {
102103
// Create a node resolver at the project root as a directory
103104
const resolver = createRequire(projectRoot + '/');
@@ -203,27 +204,6 @@ export async function normalizeOptions(
203204
};
204205
}
205206

206-
function findTailwindConfigurationFile(
207-
workspaceRoot: string,
208-
projectRoot: string,
209-
): string | undefined {
210-
// A configuration file can exist in the project or workspace root
211-
// The list of valid config files can be found:
212-
// https://github.com/tailwindlabs/tailwindcss/blob/8845d112fb62d79815b50b3bae80c317450b8b92/src/util/resolveConfigPath.js#L46-L52
213-
const tailwindConfigFiles = ['tailwind.config.js', 'tailwind.config.cjs'];
214-
for (const basePath of [projectRoot, workspaceRoot]) {
215-
for (const configFile of tailwindConfigFiles) {
216-
// Project level configuration should always take precedence.
217-
const fullPath = path.join(basePath, configFile);
218-
if (fs.existsSync(fullPath)) {
219-
return fullPath;
220-
}
221-
}
222-
}
223-
224-
return undefined;
225-
}
226-
227207
/**
228208
* Normalize a directory path string.
229209
* Currently only removes a trailing slash if present.
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/**
2+
* @license
3+
* Copyright Google LLC All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.io/license
7+
*/
8+
9+
import { readdir } from 'node:fs/promises';
10+
import { join } from 'node:path';
11+
12+
const tailwindConfigFiles: string[] = [
13+
'tailwind.config.js',
14+
'tailwind.config.cjs',
15+
'tailwind.config.mjs',
16+
'tailwind.config.ts',
17+
];
18+
19+
export async function findTailwindConfigurationFile(
20+
workspaceRoot: string,
21+
projectRoot: string,
22+
): Promise<string | undefined> {
23+
const dirEntries = [projectRoot, workspaceRoot].map((root) =>
24+
readdir(root, { withFileTypes: false }).then((entries) => ({
25+
root,
26+
files: new Set(entries),
27+
})),
28+
);
29+
30+
// A configuration file can exist in the project or workspace root
31+
for await (const { root, files } of dirEntries) {
32+
for (const potentialConfig of tailwindConfigFiles) {
33+
if (files.has(potentialConfig)) {
34+
return join(root, potentialConfig);
35+
}
36+
}
37+
}
38+
39+
return undefined;
40+
}

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

Lines changed: 7 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
*/
88

99
import MiniCssExtractPlugin from 'mini-css-extract-plugin';
10-
import * as fs from 'node:fs';
1110
import * as path from 'node:path';
1211
import { pathToFileURL } from 'node:url';
1312
import type { FileImporter } from 'sass';
@@ -19,6 +18,7 @@ import {
1918
import { SassLegacyWorkerImplementation } from '../../sass/sass-service-legacy';
2019
import { WebpackConfigOptions } from '../../utils/build-options';
2120
import { useLegacySass } from '../../utils/environment-options';
21+
import { findTailwindConfigurationFile } from '../../utils/tailwind';
2222
import {
2323
AnyComponentStyleBudgetChecker,
2424
PostcssCliResources,
@@ -34,8 +34,8 @@ import {
3434
} from '../utils/helpers';
3535

3636
// eslint-disable-next-line max-lines-per-function
37-
export function getStylesConfig(wco: WebpackConfigOptions): Configuration {
38-
const { root, buildOptions, logger } = wco;
37+
export async function getStylesConfig(wco: WebpackConfigOptions): Promise<Configuration> {
38+
const { root, buildOptions, logger, projectRoot } = wco;
3939
const extraPlugins: Configuration['plugins'] = [];
4040

4141
extraPlugins.push(new AnyComponentStyleBudgetChecker(buildOptions.budgets));
@@ -86,13 +86,13 @@ export function getStylesConfig(wco: WebpackConfigOptions): Configuration {
8686
// Only load Tailwind CSS plugin if configuration file was found.
8787
// This acts as a guard to ensure the project actually wants to use Tailwind CSS.
8888
// The package may be unknowningly present due to a third-party transitive package dependency.
89-
const tailwindConfigPath = getTailwindConfigPath(wco);
89+
const tailwindConfigPath = await findTailwindConfigurationFile(root, projectRoot);
9090
if (tailwindConfigPath) {
9191
let tailwindPackagePath;
9292
try {
93-
tailwindPackagePath = require.resolve('tailwindcss', { paths: [wco.root] });
93+
tailwindPackagePath = require.resolve('tailwindcss', { paths: [root] });
9494
} catch {
95-
const relativeTailwindConfigPath = path.relative(wco.root, tailwindConfigPath);
95+
const relativeTailwindConfigPath = path.relative(root, tailwindConfigPath);
9696
logger.warn(
9797
`Tailwind CSS configuration file found (${relativeTailwindConfigPath})` +
9898
` but the 'tailwindcss' package is not installed.` +
@@ -315,24 +315,6 @@ export function getStylesConfig(wco: WebpackConfigOptions): Configuration {
315315
};
316316
}
317317

318-
function getTailwindConfigPath({ projectRoot, root }: WebpackConfigOptions): string | undefined {
319-
// A configuration file can exist in the project or workspace root
320-
// The list of valid config files can be found:
321-
// https://github.com/tailwindlabs/tailwindcss/blob/8845d112fb62d79815b50b3bae80c317450b8b92/src/util/resolveConfigPath.js#L46-L52
322-
const tailwindConfigFiles = ['tailwind.config.js', 'tailwind.config.cjs'];
323-
for (const basePath of [projectRoot, root]) {
324-
for (const configFile of tailwindConfigFiles) {
325-
// Irrespective of the name project level configuration should always take precedence.
326-
const fullPath = path.join(basePath, configFile);
327-
if (fs.existsSync(fullPath)) {
328-
return fullPath;
329-
}
330-
}
331-
}
332-
333-
return undefined;
334-
}
335-
336318
function getSassLoaderOptions(
337319
root: string,
338320
implementation: SassWorkerImplementation | SassLegacyWorkerImplementation,
@@ -399,7 +381,7 @@ function getSassResolutionImporter(
399381
root: string,
400382
preserveSymlinks: boolean,
401383
): FileImporter<'async'> {
402-
const commonResolverOptions: Parameters<typeof loaderContext['getResolve']>[0] = {
384+
const commonResolverOptions: Parameters<(typeof loaderContext)['getResolve']>[0] = {
403385
conditionNames: ['sass', 'style'],
404386
mainFields: ['sass', 'style', 'main', '...'],
405387
extensions: ['.scss', '.sass', '.css'],

0 commit comments

Comments
 (0)