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,11 @@ 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 = string | ( ( pathData : any , assetInfo ?: any ) => string ) ;
32+
2333export interface CssExtractRspackLoaderOptions {
34+ publicPath ?: string | ( ( resourcePath : string , context : string ) => string ) ;
2435 emit ?: boolean ;
2536 esModule ?: boolean ;
2637 layer ?: string ;
@@ -29,7 +40,7 @@ export interface CssExtractRspackLoaderOptions {
2940 rootDir ?: string ;
3041}
3142
32- const PLUGIN_NAME = 'LIB_CSS_EXTRACT_LOADER' ;
43+ const LOADER_NAME = 'LIB_CSS_EXTRACT_LOADER' ;
3344
3445function stringifyLocal ( value : any ) {
3546 return typeof value === 'function' ? value . toString ( ) : JSON . stringify ( value ) ;
@@ -77,6 +88,34 @@ export const pitch: Rspack.LoaderDefinition['pitch'] = function (
7788 const filepath = this . resourcePath ;
7889 const rootDir = options . rootDir ?? this . rootContext ;
7990
91+ let { publicPath } = this . _compilation ! . outputOptions ;
92+
93+ if ( typeof options . publicPath === 'string' ) {
94+ // eslint-disable-next-line prefer-destructuring
95+ publicPath = options . publicPath ;
96+ } else if ( typeof options . publicPath === 'function' ) {
97+ publicPath = options . publicPath ( this . resourcePath , this . rootContext ) ;
98+ }
99+
100+ if ( publicPath === 'auto' ) {
101+ publicPath = AUTO_PUBLIC_PATH ;
102+ }
103+
104+ let publicPathForExtract : Filename | undefined ;
105+
106+ if ( typeof publicPath === 'string' ) {
107+ const isAbsolutePublicPath = / ^ [ a - z A - Z ] [ a - z A - Z \d + \- . ] * ?: / . test ( publicPath ) ;
108+
109+ publicPathForExtract = isAbsolutePublicPath
110+ ? publicPath
111+ : `${ ABSOLUTE_PUBLIC_PATH } ${ publicPath . replace (
112+ / \. / g,
113+ SINGLE_DOT_PATH_SEGMENT ,
114+ ) } `;
115+ } else {
116+ publicPathForExtract = publicPath ;
117+ }
118+
80119 const handleExports = (
81120 originalExports :
82121 | { default : Record < string , any > ; __esModule : true }
@@ -196,7 +235,7 @@ export const pitch: Rspack.LoaderDefinition['pitch'] = function (
196235 return '' ;
197236 } ) ( ) ;
198237
199- let resultSource = `// extracted by ${ PLUGIN_NAME } ` ;
238+ let resultSource = `// extracted by ${ LOADER_NAME } ` ;
200239
201240 let importCssFiles = '' ;
202241
@@ -249,6 +288,8 @@ export const pitch: Rspack.LoaderDefinition['pitch'] = function (
249288 `${ this . resourcePath } .webpack[javascript/auto]!=!!!${ request } ` ,
250289 {
251290 layer : options . layer ,
291+ publicPath : publicPathForExtract ,
292+ baseUri : `${ BASE_URI } /` ,
252293 } ,
253294 ( error , exports ) => {
254295 if ( error ) {
0 commit comments