@@ -322,37 +322,83 @@ class WebpackCLI implements IWebpackCLI {
322
322
process . exit ( 2 ) ;
323
323
}
324
324
325
- async tryRequireThenImport < T > ( module : ModuleName , handleError = true ) : Promise < T > {
325
+ async tryRequireThenImport < T > (
326
+ module : ModuleName ,
327
+ handleError = true ,
328
+ moduleType : "unknown" | "commonjs" | "esm" = "unknown" ,
329
+ ) : Promise < T > {
326
330
let result ;
327
331
328
- try {
329
- result = require ( module ) ;
330
- } catch ( error ) {
331
- const dynamicImportLoader : null | DynamicImport < T > =
332
- require ( "./utils/dynamic-import-loader" ) ( ) ;
333
- if (
334
- ( ( error as ImportLoaderError ) . code === "ERR_REQUIRE_ESM" ||
335
- process . env . WEBPACK_CLI_FORCE_LOAD_ESM_CONFIG ) &&
336
- pathToFileURL &&
337
- dynamicImportLoader
338
- ) {
339
- const urlForConfig = pathToFileURL ( module ) ;
340
-
341
- result = await dynamicImportLoader ( urlForConfig ) ;
342
- result = result . default ;
332
+ switch ( moduleType ) {
333
+ case "unknown" : {
334
+ try {
335
+ result = require ( module ) ;
336
+ } catch ( error ) {
337
+ const dynamicImportLoader : null | DynamicImport < T > =
338
+ require ( "./utils/dynamic-import-loader" ) ( ) ;
339
+ if (
340
+ ( ( error as ImportLoaderError ) . code === "ERR_REQUIRE_ESM" ||
341
+ process . env . WEBPACK_CLI_FORCE_LOAD_ESM_CONFIG ) &&
342
+ pathToFileURL &&
343
+ dynamicImportLoader
344
+ ) {
345
+ const urlForConfig = pathToFileURL ( module ) ;
346
+
347
+ result = await dynamicImportLoader ( urlForConfig ) ;
348
+ result = result . default ;
349
+
350
+ return result ;
351
+ }
343
352
344
- return result ;
353
+ if ( handleError ) {
354
+ this . logger . error ( error ) ;
355
+ process . exit ( 2 ) ;
356
+ } else {
357
+ throw error ;
358
+ }
359
+ }
360
+ break ;
345
361
}
362
+ case "commonjs" : {
363
+ try {
364
+ result = require ( module ) ;
365
+ } catch ( error ) {
366
+ if ( handleError ) {
367
+ this . logger . error ( error ) ;
368
+ process . exit ( 2 ) ;
369
+ } else {
370
+ throw error ;
371
+ }
372
+ }
373
+ break ;
374
+ }
375
+ case "esm" : {
376
+ try {
377
+ const dynamicImportLoader : null | DynamicImport < T > =
378
+ require ( "./utils/dynamic-import-loader" ) ( ) ;
346
379
347
- if ( handleError ) {
348
- this . logger . error ( error ) ;
349
- process . exit ( 2 ) ;
350
- } else {
351
- throw error ;
380
+ if ( pathToFileURL && dynamicImportLoader ) {
381
+ const urlForConfig = pathToFileURL ( module ) ;
382
+
383
+ result = await dynamicImportLoader ( urlForConfig ) ;
384
+ result = result . default ;
385
+
386
+ return result ;
387
+ }
388
+ } catch ( error ) {
389
+ if ( handleError ) {
390
+ this . logger . error ( error ) ;
391
+ process . exit ( 2 ) ;
392
+ } else {
393
+ throw error ;
394
+ }
395
+ }
396
+
397
+ break ;
352
398
}
353
399
}
354
400
355
- // For babel/typescript
401
+ // For babel and other, only commonjs
356
402
if ( result && typeof result === "object" && "default" in result ) {
357
403
result = result . default || { } ;
358
404
}
@@ -1749,8 +1795,15 @@ class WebpackCLI implements IWebpackCLI {
1749
1795
1750
1796
const interpret = require ( "interpret" ) ;
1751
1797
const loadConfigByPath = async ( configPath : string , argv : Argv = { } ) => {
1752
- const ext = path . extname ( configPath ) ;
1753
- const interpreted = Object . keys ( interpret . jsVariants ) . find ( ( variant ) => variant === ext ) ;
1798
+ const ext = path . extname ( configPath ) . toLowerCase ( ) ;
1799
+ let interpreted = interpret . jsVariants [ ext ] ;
1800
+
1801
+ // Fallback `.cts` to `.ts`
1802
+ // TODO implement good `.mts` support after https://github.com/gulpjs/rechoir/issues/43
1803
+ // For ESM and `.mts` you need to use: 'NODE_OPTIONS="--loader ts-node/esm" webpack-cli --config ./webpack.config.mts'
1804
+ if ( ! interpreted && / \. c t s $ / . test ( ext ) ) {
1805
+ interpreted = interpret . jsVariants [ ".ts" ] ;
1806
+ }
1754
1807
1755
1808
if ( interpreted && ! disableInterpret ) {
1756
1809
const rechoir : Rechoir = require ( "rechoir" ) ;
@@ -1777,10 +1830,24 @@ class WebpackCLI implements IWebpackCLI {
1777
1830
1778
1831
type LoadConfigOption = PotentialPromise < WebpackConfiguration > ;
1779
1832
1833
+ let moduleType : "unknown" | "commonjs" | "esm" = "unknown" ;
1834
+
1835
+ switch ( ext ) {
1836
+ case ".cjs" :
1837
+ case ".cts" :
1838
+ moduleType = "commonjs" ;
1839
+ break ;
1840
+ case ".mjs" :
1841
+ case ".mts" :
1842
+ moduleType = "esm" ;
1843
+ break ;
1844
+ }
1845
+
1780
1846
try {
1781
1847
options = await this . tryRequireThenImport < LoadConfigOption | LoadConfigOption [ ] > (
1782
1848
configPath ,
1783
1849
false ,
1850
+ moduleType ,
1784
1851
) ;
1785
1852
// @ts -expect-error error type assertion
1786
1853
} catch ( error : Error ) {
@@ -1897,14 +1964,15 @@ class WebpackCLI implements IWebpackCLI {
1897
1964
".cjs" ,
1898
1965
".ts" ,
1899
1966
".cts" ,
1967
+ ".mts" ,
1900
1968
...Object . keys ( interpret . extensions ) ,
1901
1969
] ;
1902
1970
// Order defines the priority, in decreasing order
1903
- const defaultConfigFiles = [
1904
- "webpack.config" ,
1905
- ".webpack/webpack.config" ,
1906
- ".webpack/webpackfile" ,
1907
- ] . flatMap ( ( filename ) => extensions . map ( ( ext ) => path . resolve ( filename + ext ) ) ) ;
1971
+ const defaultConfigFiles = new Set (
1972
+ [ "webpack.config" , ".webpack/webpack.config" , ".webpack/webpackfile" ] . flatMap ( ( filename ) =>
1973
+ extensions . map ( ( ext ) => path . resolve ( filename + ext ) ) ,
1974
+ ) ,
1975
+ ) ;
1908
1976
1909
1977
let foundDefaultConfigFile ;
1910
1978
0 commit comments