import { extname } from 'path' ; import type { Plugin } from 'rollup' ; import { createFilter } from 'rollup-pluginutils' ; import { walk } from 'estree-walker' ; import MagicString from 'magic-string' ; interface Options { include ? : string [ ] ; exclude ? : string [ ] ; extensions ? : string [ ] ; } const DEFAULT_OPTIONS = { include : [ '*.+(t|j)s+(|x)' , '**/*.+(t|j)s+(|x)' ] , exclude : [ '*.d.ts' , '**/*.d.ts' ] , extensions : [ 'ts' , 'tsx' , 'json' ] , } ; export const addRequireChunkPlugin = ( options = { } ) : Plugin => { const opts = { ... DEFAULT_OPTIONS , ... options , } ; const filter = createFilter ( opts . include , opts . exclude ) ; return { name : 'add-require-chunk' , transform ( code , id ) { if ( ! filter ( id ) ) { return null ; } const ast = this . parse ( code , { } ) ; const magicString = new MagicString ( code ) ; const promises = [ ] ; walk ( ast as any , { enter : ( node ) => { if ( node . type === 'CallExpression' && node . callee . name === 'require' && node . arguments [ 0 ] . type === 'Literal' ) { const arg = node . arguments [ 0 ] ; const name = arg . value ; promises . push ( this . resolve ( name , id ) . then ( ( module ) => { if ( module && ! module . external && opts . extensions . includes ( extname ( module . id ) . slice ( 1 ) ) ) { const referenceId = this . emitFile ( { type : 'chunk' , id : module . id , } ) ; magicString . overwrite ( arg . start , arg . end , `import.meta.ROLLUP_FILE_URL_${ referenceId }` ) ; } } ) ) ; } } , } ) ; return Promise . all ( promises ) . then ( ( ) => { return { code : magicString . toString ( ) } ; } ) ; } , resolveFileUrl ( { referenceId , fileName } ) { if ( referenceId ) { return `'./${ fileName }'` ; } return null ; } , } ; } ;