Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion packages/core/rslib.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import fs from 'node:fs';
import path from 'node:path';
import type { RsbuildPlugin } from '@rsbuild/core';
import { pluginPublint } from 'rsbuild-plugin-publint';
import { defineConfig } from 'rslib';
import { defineConfig, rspack } from 'rslib';

const pluginFixDtsTypes: RsbuildPlugin = {
name: 'fix-dts-types',
Expand Down Expand Up @@ -54,4 +54,9 @@ export default defineConfig({
rslog: '../compiled/rslog/index.js',
},
},
tools: {
rspack: {
plugins: [new rspack.CircularDependencyRspackPlugin({})],
},
},
});
3 changes: 2 additions & 1 deletion packages/core/src/cli/restart.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import path from 'node:path';
import { color, debounce, isTTY } from '../utils/helper';
import { color } from '../utils/color';
import { debounce, isTTY } from '../utils/helper';
import { logger } from '../utils/logger';

export async function watchFilesForRestart(
Expand Down
5 changes: 2 additions & 3 deletions packages/core/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,11 @@ import {
SWC_HELPERS,
} from './constant';
import {
type CssLoaderOptionsAuto,
RSLIB_CSS_ENTRY_FLAG,
composeCssConfig,
cssExternalHandler,
isCssGlobalFile,
} from './css/cssConfig';
import { type CssLoaderOptionsAuto, isCssGlobalFile } from './css/utils';
import { composeEntryChunkConfig } from './plugins/EntryChunkPlugin';
import {
pluginCjsImportMetaUrlShim,
Expand Down Expand Up @@ -58,11 +57,11 @@ import type {
Shims,
Syntax,
} from './types';
import { color } from './utils/color';
import { getDefaultExtension } from './utils/extension';
import {
calcLongestCommonPath,
checkMFPlugin,
color,
getAbsolutePath,
isEmptyObject,
isIntermediateOutputFormat,
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/css/LibCssExtractPlugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import {
AUTO_PUBLIC_PATH,
BASE_URI,
SINGLE_DOT_PATH_SEGMENT,
} from './libCssExtractLoader';
} from './const';
import { getUndoPath } from './utils';

const pluginName = 'LIB_CSS_EXTRACT_PLUGIN';
Expand Down
6 changes: 6 additions & 0 deletions packages/core/src/css/const.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export const BASE_URI = 'webpack://';
export const MODULE_TYPE = 'css/mini-extract';
export const AUTO_PUBLIC_PATH = '__mini_css_extract_plugin_public_path_auto__';
export const ABSOLUTE_PUBLIC_PATH: string = `${BASE_URI}/mini-css-extract-plugin/`;
export const SINGLE_DOT_PATH_SEGMENT =
'__mini_css_extract_plugin_single_dot_path_segment__';
79 changes: 6 additions & 73 deletions packages/core/src/css/cssConfig.ts
Original file line number Diff line number Diff line change
@@ -1,82 +1,15 @@
import { createRequire } from 'node:module';
import path from 'node:path';
import type {
CSSLoaderOptions,
EnvironmentConfig,
RsbuildPlugin,
} from '@rsbuild/core';
import { CSS_EXTENSIONS_PATTERN } from '../constant';
import type { EnvironmentConfig, RsbuildPlugin } from '@rsbuild/core';
import { LibCssExtractPlugin } from './LibCssExtractPlugin';
import {
type CssLoaderOptionsAuto,
isCssFile,
isCssModulesFile,
} from './utils';
const require = createRequire(import.meta.url);

export const RSLIB_CSS_ENTRY_FLAG = '__rslib_css__';

// https://rsbuild.rs/config/output/css-modules#cssmodulesauto
export type CssLoaderOptionsAuto = CSSLoaderOptions['modules'] extends infer T
? T extends { auto?: any }
? T['auto']
: never
: never;

export function isCssFile(filepath: string): boolean {
return CSS_EXTENSIONS_PATTERN.test(filepath);
}

const CSS_MODULE_REG = /\.module\.\w+$/i;

/**
* This function is modified based on
* https://github.com/web-infra-dev/rspack/blob/7b80a45a1c58de7bc506dbb107fad6fda37d2a1f/packages/rspack/src/loader-runner/index.ts#L903
*/
const PATH_QUERY_FRAGMENT_REGEXP =
/^((?:\u200b.|[^?#\u200b])*)(\?(?:\u200b.|[^#\u200b])*)?(#.*)?$/;
export function parsePathQueryFragment(str: string): {
path: string;
query: string;
fragment: string;
} {
const match = PATH_QUERY_FRAGMENT_REGEXP.exec(str);
return {
path: match?.[1]?.replace(/\u200b(.)/g, '$1') || '',
query: match?.[2] ? match[2].replace(/\u200b(.)/g, '$1') : '',
fragment: match?.[3] || '',
};
}

export function isCssModulesFile(
filepath: string,
auto: CssLoaderOptionsAuto,
): boolean {
const filename = path.basename(filepath);
if (auto === true) {
return CSS_MODULE_REG.test(filename);
}

if (auto instanceof RegExp) {
return auto.test(filepath);
}

if (typeof auto === 'function') {
const { path, query, fragment } = parsePathQueryFragment(filepath);
// this is a mock for loader
return auto(path, query, fragment);
}

return false;
}

export function isCssGlobalFile(
filepath: string,
auto: CssLoaderOptionsAuto,
): boolean {
const isCss = isCssFile(filepath);
if (!isCss) {
return false;
}
const isCssModules = isCssModulesFile(filepath, auto);
return !isCssModules;
}

type ExternalCallback = (arg0?: undefined, arg1?: string) => void;

export async function cssExternalHandler(
Expand Down
17 changes: 8 additions & 9 deletions packages/core/src/css/libCssExtractLoader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,14 @@
*/
import path, { extname } from 'node:path';
import type { Rspack } from '@rsbuild/core';
import { type CssLoaderOptionsAuto, isCssModulesFile } from './cssConfig';

export const BASE_URI = 'webpack://';
export const MODULE_TYPE = 'css/mini-extract';
export const AUTO_PUBLIC_PATH = '__mini_css_extract_plugin_public_path_auto__';
export const ABSOLUTE_PUBLIC_PATH: string = `${BASE_URI}/mini-css-extract-plugin/`;
export const SINGLE_DOT_PATH_SEGMENT =
'__mini_css_extract_plugin_single_dot_path_segment__';

import {
ABSOLUTE_PUBLIC_PATH,
AUTO_PUBLIC_PATH,
BASE_URI,
SINGLE_DOT_PATH_SEGMENT,
} from './const';

import { type CssLoaderOptionsAuto, isCssModulesFile } from './utils';
interface DependencyDescription {
identifier: string;
content: string;
Expand Down
72 changes: 70 additions & 2 deletions packages/core/src/css/utils.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,20 @@
import path from 'node:path';
import type { CSSLoaderOptions } from '@rsbuild/core';
import { CSS_EXTENSIONS_PATTERN } from '../constant';

// https://rsbuild.rs/config/output/css-modules#cssmodulesauto
export type CssLoaderOptionsAuto = CSSLoaderOptions['modules'] extends infer T
? T extends { auto?: any }
? T['auto']
: never
: never;

/**
* This function is copied from
* https://github.com/webpack-contrib/mini-css-extract-plugin/blob/3effaa0319bad5cc1bf0ae760553bf7abcbc35a4/src/utils.js#L169
* linted by biome
*/
function getUndoPath(
export function getUndoPath(
filename: string,
outputPathArg: string,
enforceRelative: boolean,
Expand Down Expand Up @@ -42,4 +53,61 @@ function getUndoPath(
: append;
}

export { getUndoPath };
export function isCssFile(filepath: string): boolean {
return CSS_EXTENSIONS_PATTERN.test(filepath);
}

const CSS_MODULE_REG = /\.module\.\w+$/i;

/**
* This function is modified based on
* https://github.com/web-infra-dev/rspack/blob/7b80a45a1c58de7bc506dbb107fad6fda37d2a1f/packages/rspack/src/loader-runner/index.ts#L903
*/
const PATH_QUERY_FRAGMENT_REGEXP =
/^((?:\u200b.|[^?#\u200b])*)(\?(?:\u200b.|[^#\u200b])*)?(#.*)?$/;
export function parsePathQueryFragment(str: string): {
path: string;
query: string;
fragment: string;
} {
const match = PATH_QUERY_FRAGMENT_REGEXP.exec(str);
return {
path: match?.[1]?.replace(/\u200b(.)/g, '$1') || '',
query: match?.[2] ? match[2].replace(/\u200b(.)/g, '$1') : '',
fragment: match?.[3] || '',
};
}

export function isCssModulesFile(
filepath: string,
auto: CssLoaderOptionsAuto,
): boolean {
const filename = path.basename(filepath);
if (auto === true) {
return CSS_MODULE_REG.test(filename);
}

if (auto instanceof RegExp) {
return auto.test(filepath);
}

if (typeof auto === 'function') {
const { path, query, fragment } = parsePathQueryFragment(filepath);
// this is a mock for loader
return auto(path, query, fragment);
}

return false;
}

export function isCssGlobalFile(
filepath: string,
auto: CssLoaderOptionsAuto,
): boolean {
const isCss = isCssFile(filepath);
if (!isCss) {
return false;
}
const isCssModules = isCssModulesFile(filepath, auto);
return !isCssModules;
}
2 changes: 2 additions & 0 deletions packages/core/src/utils/color.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import color from 'picocolors';
export { color };
4 changes: 1 addition & 3 deletions packages/core/src/utils/helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ import fs from 'node:fs';
import fsP from 'node:fs/promises';
import path, { isAbsolute, join } from 'node:path';
import type { RsbuildPlugins } from '@rsbuild/core';
import color from 'picocolors';

import type { Format, LibConfig, PkgJson } from '../types';
import { color } from './color';
import { logger } from './logger';

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

export { color };

const windowsSlashRegex = /\\/g;
export function normalizeSlash(p: string): string {
return p.replace(windowsSlashRegex, '/');
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/utils/logger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
* and important alerts that require attention.
*/
import { type Logger, logger } from 'rslog';
import { color } from './helper';
import { color } from './color';

export const isDebug = (): boolean => {
if (!process.env.DEBUG) {
Expand Down
Loading