@@ -5,6 +5,12 @@ const rspackConfigPath = path.resolve(__dirname, '../config/rspack/rspack.config
55const shakapackerBinPath = path . resolve ( __dirname , '../bin/shakapacker' ) ;
66const clientConfigPath = path . resolve ( __dirname , '../config/webpack/clientWebpackConfig.js' ) ;
77const serverConfigPath = path . resolve ( __dirname , '../config/webpack/serverWebpackConfig.js' ) ;
8+ const rscConfigPath = path . resolve ( __dirname , '../config/webpack/rscWebpackConfig.js' ) ;
9+
10+ afterEach ( ( ) => {
11+ jest . resetModules ( ) ;
12+ jest . clearAllMocks ( ) ;
13+ } ) ;
814
915describe ( 'Pro dummy RSC rspack config' , ( ) => {
1016 it ( 'provides a rspack entrypoint that delegates to the shared build config' , ( ) => {
@@ -46,4 +52,51 @@ describe('Pro dummy RSC rspack config', () => {
4652 expect ( clientSource ) . toContain ( 'path: false' ) ;
4753 expect ( clientSource ) . toContain ( 'stream: false' ) ;
4854 } ) ;
55+
56+ it ( 'wraps function-shaped JavaScript loader rules once for the RSC loader' , ( ) => {
57+ jest . doMock ( 'shakapacker' , ( ) => ( {
58+ config : {
59+ source_entry_path : 'packs' ,
60+ source_path : 'client/app' ,
61+ } ,
62+ } ) ) ;
63+
64+ const functionRule = {
65+ use ( ) {
66+ return [ { loader : 'babel-loader' , options : { caller : { ssr : true } } } ] ;
67+ } ,
68+ } ;
69+ const serverConfig = {
70+ entry : { 'server-bundle' : './server-bundle.js' } ,
71+ module : { rules : [ functionRule ] } ,
72+ output : { } ,
73+ plugins : [ ] ,
74+ resolve : { alias : { } } ,
75+ } ;
76+ const configureServer = jest . fn ( ( ) => serverConfig ) ;
77+ const extractLoader = ( rule , loaderName ) =>
78+ Array . isArray ( rule . use ) ? rule . use . find ( ( item ) => item ?. loader ?. includes ( loaderName ) ) : null ;
79+
80+ jest . doMock ( serverConfigPath , ( ) => ( {
81+ default : configureServer ,
82+ extractLoader,
83+ } ) ) ;
84+
85+ // eslint-disable-next-line global-require, import/no-dynamic-require
86+ const configureRsc = require ( rscConfigPath ) ;
87+ const firstConfig = configureRsc ( ) ;
88+ const wrappedUse = firstConfig . module . rules [ 0 ] . use ;
89+ const firstUseResult = wrappedUse ( { } ) ;
90+
91+ configureRsc ( ) ;
92+ const secondUseResult = firstConfig . module . rules [ 0 ] . use ( { } ) ;
93+
94+ expect ( configureServer ) . toHaveBeenCalledWith ( true ) ;
95+ expect ( wrappedUse . name ) . toBe ( 'rscLoaderWrapper' ) ;
96+ expect ( firstUseResult ) . toEqual ( [
97+ { loader : 'babel-loader' , options : { caller : { ssr : true } } } ,
98+ { loader : 'react-on-rails-rsc/WebpackLoader' } ,
99+ ] ) ;
100+ expect ( secondUseResult ) . toEqual ( firstUseResult ) ;
101+ } ) ;
49102} ) ;
0 commit comments