11// mock helper functions not tested directly in this file
22import './mocks' ;
33
4+ import type { ModuleRuleUseProperty , WebpackModuleRule } from '../../src/config/types' ;
45import {
56 clientBuildContext ,
67 clientWebpackConfig ,
@@ -38,6 +39,29 @@ declare global {
3839 }
3940}
4041
42+ function applyRuleToResource ( rule : WebpackModuleRule , resourcePath : string ) : ModuleRuleUseProperty [ ] {
43+ const applications = [ ] ;
44+
45+ let shouldApply : boolean = false ;
46+ if ( typeof rule . test === 'function' ) {
47+ shouldApply = rule . test ( resourcePath ) ;
48+ } else if ( rule . test instanceof RegExp ) {
49+ shouldApply = ! ! resourcePath . match ( rule . test ) ;
50+ } else if ( rule . test ) {
51+ shouldApply = resourcePath === rule . test ;
52+ }
53+
54+ if ( shouldApply ) {
55+ if ( Array . isArray ( rule . use ) ) {
56+ applications . push ( ...rule . use ) ;
57+ } else if ( rule . use ) {
58+ applications . push ( rule . use ) ;
59+ }
60+ }
61+
62+ return applications ;
63+ }
64+
4165describe ( 'webpack loaders' , ( ) => {
4266 describe ( 'server loaders' , ( ) => {
4367 it ( 'adds server `valueInjection` loader to server config' , async ( ) => {
@@ -60,6 +84,128 @@ describe('webpack loaders', () => {
6084 ] ,
6185 } ) ;
6286 } ) ;
87+
88+ it . each ( [
89+ {
90+ resourcePath : '/Users/Maisey/projects/squirrelChasingSimulator/src/pages/testPage.tsx' ,
91+ expectedWrappingTargetKind : 'page' ,
92+ } ,
93+ {
94+ resourcePath : './src/pages/testPage.tsx' ,
95+ expectedWrappingTargetKind : 'page' ,
96+ } ,
97+ {
98+ resourcePath : './pages/testPage.tsx' ,
99+ expectedWrappingTargetKind : undefined ,
100+ } ,
101+ {
102+ resourcePath : '../src/pages/testPage.tsx' ,
103+ expectedWrappingTargetKind : undefined ,
104+ } ,
105+ {
106+ resourcePath : '/Users/Maisey/projects/squirrelChasingSimulator/src/pages/nested/testPage.ts' ,
107+ expectedWrappingTargetKind : 'page' ,
108+ } ,
109+ {
110+ resourcePath : '/Users/Maisey/projects/squirrelChasingSimulator/src/pages/nested/testPage.js' ,
111+ expectedWrappingTargetKind : 'page' ,
112+ } ,
113+ {
114+ resourcePath : '/Users/Maisey/projects/squirrelChasingSimulator/src/pages/[nested]/[testPage].js' ,
115+ expectedWrappingTargetKind : 'page' ,
116+ } ,
117+ {
118+ resourcePath : '/Users/Maisey/projects/squirrelChasingSimulator/src/pages/[...testPage].js' ,
119+ expectedWrappingTargetKind : 'page' ,
120+ } ,
121+ {
122+ resourcePath : '/Users/Maisey/projects/squirrelChasingSimulator/src/middleware.js' ,
123+ expectedWrappingTargetKind : 'middleware' ,
124+ } ,
125+ {
126+ resourcePath : './src/middleware.js' ,
127+ expectedWrappingTargetKind : 'middleware' ,
128+ } ,
129+ {
130+ resourcePath : './middleware.js' ,
131+ expectedWrappingTargetKind : undefined ,
132+ } ,
133+ {
134+ resourcePath : '/Users/Maisey/projects/squirrelChasingSimulator/src/middleware.ts' ,
135+ expectedWrappingTargetKind : 'middleware' ,
136+ } ,
137+ {
138+ resourcePath : '/Users/Maisey/projects/squirrelChasingSimulator/src/middleware.tsx' ,
139+ expectedWrappingTargetKind : undefined ,
140+ } ,
141+ {
142+ resourcePath : '/Users/Maisey/projects/squirrelChasingSimulator/src/pages/api/testApiRoute.ts' ,
143+ expectedWrappingTargetKind : 'api-route' ,
144+ } ,
145+ {
146+ resourcePath : './src/pages/api/testApiRoute.ts' ,
147+ expectedWrappingTargetKind : 'api-route' ,
148+ } ,
149+ {
150+ resourcePath : '/Users/Maisey/projects/squirrelChasingSimulator/src/pages/api/nested/testApiRoute.js' ,
151+ expectedWrappingTargetKind : 'api-route' ,
152+ } ,
153+ {
154+ resourcePath : '/Users/Maisey/projects/squirrelChasingSimulator/src/app/page.js' ,
155+ expectedWrappingTargetKind : 'page-server-component' ,
156+ } ,
157+ {
158+ resourcePath : '/Users/Maisey/projects/squirrelChasingSimulator/src/app/nested/page.js' ,
159+ expectedWrappingTargetKind : 'page-server-component' ,
160+ } ,
161+ {
162+ resourcePath : '/Users/Maisey/projects/squirrelChasingSimulator/src/app/nested/page.ts' , // ts is not a valid file ending for pages in the app dir
163+ expectedWrappingTargetKind : undefined ,
164+ } ,
165+ {
166+ resourcePath : '/Users/Maisey/projects/squirrelChasingSimulator/src/app/(group)/nested/page.tsx' ,
167+ expectedWrappingTargetKind : 'page-server-component' ,
168+ } ,
169+ {
170+ resourcePath : '/Users/Maisey/projects/squirrelChasingSimulator/src/app/(group)/nested/loading.ts' ,
171+ expectedWrappingTargetKind : undefined ,
172+ } ,
173+ {
174+ resourcePath : '/Users/Maisey/projects/squirrelChasingSimulator/src/app/layout.js' ,
175+ expectedWrappingTargetKind : undefined ,
176+ } ,
177+ ] ) (
178+ 'should apply the right wrappingTargetKind with wrapping loader ($resourcePath)' ,
179+ async ( { resourcePath, expectedWrappingTargetKind } ) => {
180+ const finalWebpackConfig = await materializeFinalWebpackConfig ( {
181+ exportedNextConfig,
182+ incomingWebpackConfig : serverWebpackConfig ,
183+ incomingWebpackBuildContext : serverBuildContext ,
184+ } ) ;
185+
186+ const loaderApplications : ModuleRuleUseProperty [ ] = [ ] ;
187+ finalWebpackConfig . module . rules . forEach ( rule => {
188+ loaderApplications . push ( ...applyRuleToResource ( rule , resourcePath ) ) ;
189+ } ) ;
190+
191+ if ( expectedWrappingTargetKind ) {
192+ expect ( loaderApplications ) . toContainEqual (
193+ expect . objectContaining ( {
194+ loader : expect . stringMatching ( / w r a p p i n g L o a d e r \. j s $ / ) ,
195+ options : expect . objectContaining ( {
196+ wrappingTargetKind : expectedWrappingTargetKind ,
197+ } ) ,
198+ } ) ,
199+ ) ;
200+ } else {
201+ expect ( loaderApplications ) . not . toContainEqual (
202+ expect . objectContaining ( {
203+ loader : expect . stringMatching ( / w r a p p i n g L o a d e r \. j s $ / ) ,
204+ } ) ,
205+ ) ;
206+ }
207+ } ,
208+ ) ;
63209 } ) ;
64210
65211 describe ( 'client loaders' , ( ) => {
0 commit comments