Skip to content

Commit c90c3dd

Browse files
authored
refactor: remove circular dependency and add plugin to detect (#1070)
1 parent 0de535e commit c90c3dd

File tree

11 files changed

+105
-94
lines changed

11 files changed

+105
-94
lines changed

packages/core/rslib.config.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import fs from 'node:fs';
22
import path from 'node:path';
33
import type { RsbuildPlugin } from '@rsbuild/core';
44
import { pluginPublint } from 'rsbuild-plugin-publint';
5-
import { defineConfig } from 'rslib';
5+
import { defineConfig, rspack } from 'rslib';
66

77
const pluginFixDtsTypes: RsbuildPlugin = {
88
name: 'fix-dts-types',
@@ -54,4 +54,9 @@ export default defineConfig({
5454
rslog: '../compiled/rslog/index.js',
5555
},
5656
},
57+
tools: {
58+
rspack: {
59+
plugins: [new rspack.CircularDependencyRspackPlugin({})],
60+
},
61+
},
5762
});

packages/core/src/cli/restart.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import path from 'node:path';
2-
import { color, debounce, isTTY } from '../utils/helper';
2+
import { color } from '../utils/color';
3+
import { debounce, isTTY } from '../utils/helper';
34
import { logger } from '../utils/logger';
45

56
export async function watchFilesForRestart(

packages/core/src/config.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,11 @@ import {
2323
SWC_HELPERS,
2424
} from './constant';
2525
import {
26-
type CssLoaderOptionsAuto,
2726
RSLIB_CSS_ENTRY_FLAG,
2827
composeCssConfig,
2928
cssExternalHandler,
30-
isCssGlobalFile,
3129
} from './css/cssConfig';
30+
import { type CssLoaderOptionsAuto, isCssGlobalFile } from './css/utils';
3231
import { composeEntryChunkConfig } from './plugins/EntryChunkPlugin';
3332
import {
3433
pluginCjsImportMetaUrlShim,
@@ -58,11 +57,11 @@ import type {
5857
Shims,
5958
Syntax,
6059
} from './types';
60+
import { color } from './utils/color';
6161
import { getDefaultExtension } from './utils/extension';
6262
import {
6363
calcLongestCommonPath,
6464
checkMFPlugin,
65-
color,
6665
getAbsolutePath,
6766
isEmptyObject,
6867
isIntermediateOutputFormat,

packages/core/src/css/LibCssExtractPlugin.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import {
44
AUTO_PUBLIC_PATH,
55
BASE_URI,
66
SINGLE_DOT_PATH_SEGMENT,
7-
} from './libCssExtractLoader';
7+
} from './const';
88
import { getUndoPath } from './utils';
99

1010
const pluginName = 'LIB_CSS_EXTRACT_PLUGIN';

packages/core/src/css/const.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
export const BASE_URI = 'webpack://';
2+
export const MODULE_TYPE = 'css/mini-extract';
3+
export const AUTO_PUBLIC_PATH = '__mini_css_extract_plugin_public_path_auto__';
4+
export const ABSOLUTE_PUBLIC_PATH: string = `${BASE_URI}/mini-css-extract-plugin/`;
5+
export const SINGLE_DOT_PATH_SEGMENT =
6+
'__mini_css_extract_plugin_single_dot_path_segment__';

packages/core/src/css/cssConfig.ts

Lines changed: 6 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -1,82 +1,15 @@
11
import { createRequire } from 'node:module';
2-
import path from 'node:path';
3-
import type {
4-
CSSLoaderOptions,
5-
EnvironmentConfig,
6-
RsbuildPlugin,
7-
} from '@rsbuild/core';
8-
import { CSS_EXTENSIONS_PATTERN } from '../constant';
2+
import type { EnvironmentConfig, RsbuildPlugin } from '@rsbuild/core';
93
import { LibCssExtractPlugin } from './LibCssExtractPlugin';
4+
import {
5+
type CssLoaderOptionsAuto,
6+
isCssFile,
7+
isCssModulesFile,
8+
} from './utils';
109
const require = createRequire(import.meta.url);
1110

1211
export const RSLIB_CSS_ENTRY_FLAG = '__rslib_css__';
1312

14-
// https://rsbuild.rs/config/output/css-modules#cssmodulesauto
15-
export type CssLoaderOptionsAuto = CSSLoaderOptions['modules'] extends infer T
16-
? T extends { auto?: any }
17-
? T['auto']
18-
: never
19-
: never;
20-
21-
export function isCssFile(filepath: string): boolean {
22-
return CSS_EXTENSIONS_PATTERN.test(filepath);
23-
}
24-
25-
const CSS_MODULE_REG = /\.module\.\w+$/i;
26-
27-
/**
28-
* This function is modified based on
29-
* https://github.com/web-infra-dev/rspack/blob/7b80a45a1c58de7bc506dbb107fad6fda37d2a1f/packages/rspack/src/loader-runner/index.ts#L903
30-
*/
31-
const PATH_QUERY_FRAGMENT_REGEXP =
32-
/^((?:\u200b.|[^?#\u200b])*)(\?(?:\u200b.|[^#\u200b])*)?(#.*)?$/;
33-
export function parsePathQueryFragment(str: string): {
34-
path: string;
35-
query: string;
36-
fragment: string;
37-
} {
38-
const match = PATH_QUERY_FRAGMENT_REGEXP.exec(str);
39-
return {
40-
path: match?.[1]?.replace(/\u200b(.)/g, '$1') || '',
41-
query: match?.[2] ? match[2].replace(/\u200b(.)/g, '$1') : '',
42-
fragment: match?.[3] || '',
43-
};
44-
}
45-
46-
export function isCssModulesFile(
47-
filepath: string,
48-
auto: CssLoaderOptionsAuto,
49-
): boolean {
50-
const filename = path.basename(filepath);
51-
if (auto === true) {
52-
return CSS_MODULE_REG.test(filename);
53-
}
54-
55-
if (auto instanceof RegExp) {
56-
return auto.test(filepath);
57-
}
58-
59-
if (typeof auto === 'function') {
60-
const { path, query, fragment } = parsePathQueryFragment(filepath);
61-
// this is a mock for loader
62-
return auto(path, query, fragment);
63-
}
64-
65-
return false;
66-
}
67-
68-
export function isCssGlobalFile(
69-
filepath: string,
70-
auto: CssLoaderOptionsAuto,
71-
): boolean {
72-
const isCss = isCssFile(filepath);
73-
if (!isCss) {
74-
return false;
75-
}
76-
const isCssModules = isCssModulesFile(filepath, auto);
77-
return !isCssModules;
78-
}
79-
8013
type ExternalCallback = (arg0?: undefined, arg1?: string) => void;
8114

8215
export async function cssExternalHandler(

packages/core/src/css/libCssExtractLoader.ts

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,14 @@
77
*/
88
import path, { extname } from 'node:path';
99
import type { Rspack } from '@rsbuild/core';
10-
import { type CssLoaderOptionsAuto, isCssModulesFile } from './cssConfig';
11-
12-
export const BASE_URI = 'webpack://';
13-
export const MODULE_TYPE = 'css/mini-extract';
14-
export const AUTO_PUBLIC_PATH = '__mini_css_extract_plugin_public_path_auto__';
15-
export const ABSOLUTE_PUBLIC_PATH: string = `${BASE_URI}/mini-css-extract-plugin/`;
16-
export const SINGLE_DOT_PATH_SEGMENT =
17-
'__mini_css_extract_plugin_single_dot_path_segment__';
18-
10+
import {
11+
ABSOLUTE_PUBLIC_PATH,
12+
AUTO_PUBLIC_PATH,
13+
BASE_URI,
14+
SINGLE_DOT_PATH_SEGMENT,
15+
} from './const';
16+
17+
import { type CssLoaderOptionsAuto, isCssModulesFile } from './utils';
1918
interface DependencyDescription {
2019
identifier: string;
2120
content: string;

packages/core/src/css/utils.ts

Lines changed: 70 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,20 @@
1+
import path from 'node:path';
2+
import type { CSSLoaderOptions } from '@rsbuild/core';
3+
import { CSS_EXTENSIONS_PATTERN } from '../constant';
4+
5+
// https://rsbuild.rs/config/output/css-modules#cssmodulesauto
6+
export type CssLoaderOptionsAuto = CSSLoaderOptions['modules'] extends infer T
7+
? T extends { auto?: any }
8+
? T['auto']
9+
: never
10+
: never;
11+
112
/**
213
* This function is copied from
314
* https://github.com/webpack-contrib/mini-css-extract-plugin/blob/3effaa0319bad5cc1bf0ae760553bf7abcbc35a4/src/utils.js#L169
415
* linted by biome
516
*/
6-
function getUndoPath(
17+
export function getUndoPath(
718
filename: string,
819
outputPathArg: string,
920
enforceRelative: boolean,
@@ -42,4 +53,61 @@ function getUndoPath(
4253
: append;
4354
}
4455

45-
export { getUndoPath };
56+
export function isCssFile(filepath: string): boolean {
57+
return CSS_EXTENSIONS_PATTERN.test(filepath);
58+
}
59+
60+
const CSS_MODULE_REG = /\.module\.\w+$/i;
61+
62+
/**
63+
* This function is modified based on
64+
* https://github.com/web-infra-dev/rspack/blob/7b80a45a1c58de7bc506dbb107fad6fda37d2a1f/packages/rspack/src/loader-runner/index.ts#L903
65+
*/
66+
const PATH_QUERY_FRAGMENT_REGEXP =
67+
/^((?:\u200b.|[^?#\u200b])*)(\?(?:\u200b.|[^#\u200b])*)?(#.*)?$/;
68+
export function parsePathQueryFragment(str: string): {
69+
path: string;
70+
query: string;
71+
fragment: string;
72+
} {
73+
const match = PATH_QUERY_FRAGMENT_REGEXP.exec(str);
74+
return {
75+
path: match?.[1]?.replace(/\u200b(.)/g, '$1') || '',
76+
query: match?.[2] ? match[2].replace(/\u200b(.)/g, '$1') : '',
77+
fragment: match?.[3] || '',
78+
};
79+
}
80+
81+
export function isCssModulesFile(
82+
filepath: string,
83+
auto: CssLoaderOptionsAuto,
84+
): boolean {
85+
const filename = path.basename(filepath);
86+
if (auto === true) {
87+
return CSS_MODULE_REG.test(filename);
88+
}
89+
90+
if (auto instanceof RegExp) {
91+
return auto.test(filepath);
92+
}
93+
94+
if (typeof auto === 'function') {
95+
const { path, query, fragment } = parsePathQueryFragment(filepath);
96+
// this is a mock for loader
97+
return auto(path, query, fragment);
98+
}
99+
100+
return false;
101+
}
102+
103+
export function isCssGlobalFile(
104+
filepath: string,
105+
auto: CssLoaderOptionsAuto,
106+
): boolean {
107+
const isCss = isCssFile(filepath);
108+
if (!isCss) {
109+
return false;
110+
}
111+
const isCssModules = isCssModulesFile(filepath, auto);
112+
return !isCssModules;
113+
}

packages/core/src/utils/color.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
import color from 'picocolors';
2+
export { color };

packages/core/src/utils/helper.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@ import fs from 'node:fs';
22
import fsP from 'node:fs/promises';
33
import path, { isAbsolute, join } from 'node:path';
44
import type { RsbuildPlugins } from '@rsbuild/core';
5-
import color from 'picocolors';
65

76
import type { Format, LibConfig, PkgJson } from '../types';
7+
import { color } from './color';
88
import { logger } from './logger';
99

1010
/**
@@ -242,8 +242,6 @@ export const isIntermediateOutputFormat = (format: Format): boolean => {
242242
return format === 'cjs' || format === 'esm';
243243
};
244244

245-
export { color };
246-
247245
const windowsSlashRegex = /\\/g;
248246
export function normalizeSlash(p: string): string {
249247
return p.replace(windowsSlashRegex, '/');

0 commit comments

Comments
 (0)