@@ -31,12 +31,13 @@ export interface RawPluginOptions {
3131 loader ?: "text" | "base64" | "dataurl" | "file" | "binary" | "default" ;
3232
3333 /**
34- * Extensions to be treated as text files.
34+ * Map file extensions (without dot) to custom loaders.
35+ * Example: { md: "text", png: "dataurl" }
3536 */
36- textExtensions ?: string [ ] ;
37+ customLoaders ?: Record < string , "text" | "base64" | "dataurl" | "file" | "binary" | "default" > ;
3738
3839 /**
39- * Extension name in case you are using some other extension with conflicting names.
40+ * Plugin name override (for debugging, deduplication, etc.)
4041 */
4142 name ?: string ;
4243}
@@ -54,8 +55,10 @@ export const raw = (options?: RawPluginOptions): Plugin => ({
5455 const ext = options ?. ext ?. map ( e => e . replace ( / ^ \. / , "" ) ) ?? DEFAULT_EXT_ORDER_LIST ;
5556
5657 build . onResolve ( { filter : / \? ( r a w | t e x t | b u f f e r | b i n a r y | b a s e 6 4 | d a t a u r l | f i l e ) $ / } , args => {
57- const query = args . path . split ( "?" ) . pop ( ) ;
58- const filepath = args . path . replace ( new RegExp ( `\\?${ query } $` ) , "" ) ;
58+ const i = args . path . lastIndexOf ( "?" ) ;
59+ const filepath = i !== - 1 ? args . path . slice ( 0 , i ) : args . path ;
60+ const query = i !== - 1 ? args . path . slice ( i + 1 ) : undefined ;
61+
5962 return {
6063 path : filepath ,
6164 namespace : "raw" ,
@@ -111,20 +114,25 @@ export const raw = (options?: RawPluginOptions): Plugin => ({
111114 return { contents : buffer , loader } ;
112115 } ) ;
113116
114- if ( options ?. textExtensions ?. length ) {
115- build . onLoad (
116- {
117- filter : new RegExp (
118- `\\.(${ options . textExtensions
119- . map ( e => e . replace ( / ^ \. / , "" ) . replace ( / [ . * + ? ^ $ { } ( ) | [ \] \\ ] / g, "\\$&" ) )
120- . join ( "|" ) } )$`,
121- ) ,
122- } ,
123- args => ( {
124- contents : fs . readFileSync ( args . path ) ,
125- loader : "text" ,
126- } ) ,
117+ if ( options ?. customLoaders ) {
118+ const customLoaderKeys = Object . keys ( options . customLoaders ) . sort (
119+ ( a , b ) => b . length - a . length ,
120+ ) ;
121+ const pattern = new RegExp (
122+ `\\.(${ customLoaderKeys
123+ . map ( e => e . replace ( / ^ \. / , "" ) . replace ( / [ . * + ? ^ $ { } ( ) | [ \] \\ ] / g, "\\$&" ) )
124+ . join ( "|" ) } )$`,
127125 ) ;
126+
127+ build . onLoad ( { filter : pattern } , args => {
128+ const path = args . path ;
129+ const loaderKey = customLoaderKeys . find ( suffix => path . endsWith ( suffix ) ) ;
130+ const loader = options . customLoaders ?. [ loaderKey ?? "" ] ;
131+ if ( ! loader ) return ;
132+
133+ const buffer = fs . readFileSync ( path ) ;
134+ return { contents : buffer , loader } ;
135+ } ) ;
128136 }
129137 } ,
130138} ) ;
0 commit comments