33 * https://github.com/web-infra-dev/rspack/blob/0a89e433a9f8596a7c6c4326542f168b5982d2da/packages/rspack/src/builtin-plugin/css-extract/loader.ts
44 * 1. remove hmr/webpack runtime
55 * 2. add `this.emitFile` to emit css files
6- * 3. add `import './[name].css';`
6+ * 3. add `import './[name].css';` to js module
77 */
88import path , { extname } from 'node:path' ;
99import type { Rspack } from '@rsbuild/core' ;
1010
11+ export const BASE_URI = "webpack://" ;
12+ export const MODULE_TYPE = "css/mini-extract" ;
13+ export const AUTO_PUBLIC_PATH = "__mini_css_extract_plugin_public_path_auto__" ;
14+ export const ABSOLUTE_PUBLIC_PATH : string = `${ BASE_URI } /mini-css-extract-plugin/` ;
15+ export const SINGLE_DOT_PATH_SEGMENT =
16+ "__mini_css_extract_plugin_single_dot_path_segment__" ;
17+
1118interface DependencyDescription {
1219 identifier : string ;
1320 content : string ;
@@ -20,7 +27,13 @@ interface DependencyDescription {
2027 filepath : string ;
2128}
2229
30+ // https://github.com/web-infra-dev/rspack/blob/c0986d39b7d647682f10fcef5bbade39fd016eca/packages/rspack/src/config/types.ts#L10
31+ type Filename =
32+ | string
33+ | ( ( pathData : any , assetInfo ?: any ) => string ) ;
34+
2335export interface CssExtractRspackLoaderOptions {
36+ publicPath ?: string | ( ( resourcePath : string , context : string ) => string ) ;
2437 emit ?: boolean ;
2538 esModule ?: boolean ;
2639 layer ?: string ;
@@ -29,7 +42,7 @@ export interface CssExtractRspackLoaderOptions {
2942 rootDir ?: string ;
3043}
3144
32- const PLUGIN_NAME = 'LIB_CSS_EXTRACT_LOADER' ;
45+ const LOADER_NAME = 'LIB_CSS_EXTRACT_LOADER' ;
3346
3447function stringifyLocal ( value : any ) {
3548 return typeof value === 'function' ? value . toString ( ) : JSON . stringify ( value ) ;
@@ -77,6 +90,35 @@ export const pitch: Rspack.LoaderDefinition['pitch'] = function (
7790 const filepath = this . resourcePath ;
7891 const rootDir = options . rootDir ?? this . rootContext ;
7992
93+ let { publicPath } = this . _compilation ! . outputOptions ;
94+
95+
96+ if ( typeof options . publicPath === "string" ) {
97+ // eslint-disable-next-line prefer-destructuring
98+ publicPath = options . publicPath ;
99+ } else if ( typeof options . publicPath === "function" ) {
100+ publicPath = options . publicPath ( this . resourcePath , this . rootContext ) ;
101+ }
102+
103+ if ( publicPath === "auto" ) {
104+ publicPath = AUTO_PUBLIC_PATH ;
105+ }
106+
107+ let publicPathForExtract : Filename | undefined ;
108+
109+ if ( typeof publicPath === "string" ) {
110+ const isAbsolutePublicPath = / ^ [ a - z A - Z ] [ a - z A - Z \d + \- . ] * ?: / . test ( publicPath ) ;
111+
112+ publicPathForExtract = isAbsolutePublicPath
113+ ? publicPath
114+ : `${ ABSOLUTE_PUBLIC_PATH } ${ publicPath . replace (
115+ / \. / g,
116+ SINGLE_DOT_PATH_SEGMENT
117+ ) } `;
118+ } else {
119+ publicPathForExtract = publicPath ;
120+ }
121+
80122 const handleExports = (
81123 originalExports :
82124 | { default : Record < string , any > ; __esModule : true }
@@ -196,7 +238,7 @@ export const pitch: Rspack.LoaderDefinition['pitch'] = function (
196238 return '' ;
197239 } ) ( ) ;
198240
199- let resultSource = `// extracted by ${ PLUGIN_NAME } ` ;
241+ let resultSource = `// extracted by ${ LOADER_NAME } ` ;
200242
201243 let importCssFiles = '' ;
202244
@@ -249,6 +291,8 @@ export const pitch: Rspack.LoaderDefinition['pitch'] = function (
249291 `${ this . resourcePath } .webpack[javascript/auto]!=!!!${ request } ` ,
250292 {
251293 layer : options . layer ,
294+ publicPath : publicPathForExtract ,
295+ baseUri : `${ BASE_URI } /` ,
252296 } ,
253297 ( error , exports ) => {
254298 if ( error ) {
0 commit comments