1+ /* eslint-disable global-require */
2+ /* eslint-disable import/no-dynamic-require */
13const path = require ( 'path' ) ;
24const fs = require ( 'fs' ) ;
35const webpack = require ( 'webpack' ) ;
@@ -49,9 +51,7 @@ module.exports = (env, argv) => {
4951 vendors: any;
5052 devServerProxy: any;
5153 } */
52- // eslint-disable-next-line global-require,import/no-dynamic-require
5354 const workspaceYoRcFile = fs . existsSync ( path . join ( workspacePath , '.yo-rc-workspace.json' ) ) ? require ( path . join ( workspacePath , '.yo-rc-workspace.json' ) ) : { } ;
54- // eslint-disable-next-line global-require,import/no-dynamic-require
5555 const workspacePkg = require ( path . join ( workspacePath , 'package.json' ) ) ;
5656 const workspaceBuildInfoFile = path . join ( workspacePath , 'package-lock.json' ) ;
5757 const workspaceMetaDataFile = path . join ( workspacePath , 'metaData.json' ) ;
@@ -61,10 +61,15 @@ module.exports = (env, argv) => {
6161 const workspaceProxy = workspaceYoRcFile . devServerProxy || { } ;
6262 const workspaceRepos = isSingleRepoMode ? [ './' ] : workspaceYoRcFile . frontendRepos || [ ] ;
6363 const workspaceMaxChunkSize = workspaceYoRcFile . maxChunkSize || 5000000 ;
64+ const resolveAliases = Object . fromEntries ( Object . entries ( workspaceYoRcFile . resolveAliases || { } ) . map ( ( [ key , p ] ) => [ key , path . join ( workspacePath , p ) ] ) ) ;
65+ // Use a regex with capturing group as explained in https://github.com/webpack/webpack/pull/14509#issuecomment-1237348087.
66+ const customResolveAliasRegex = Object . entries ( resolveAliases ) . length > 0 ? new RegExp ( `/^(.+?[\\/]node_modules[\\/](?!(${ Object . keys ( resolveAliases ) . join ( '|' ) } ))(@.+?[\\/])?.+?)[\\/]/` ) : null ;
67+ Object . entries ( resolveAliases ) . forEach ( ( [ key , p ] ) => console . log ( `Using custom resolve alias: ${ key } -> ${ p } ` ) ) ;
68+
69+ const workspaceRepoToName = Object . fromEntries ( workspaceRepos . map ( ( r ) => [ r , require ( path . join ( workspacePath , r , 'package.json' ) ) . name ] ) ) ;
6470
6571 const defaultApp = isSingleRepoMode ? './' : workspaceYoRcFile . defaultApp ;
6672 const defaultAppPath = path . join ( workspacePath , defaultApp ) ;
67- // eslint-disable-next-line global-require,import/no-dynamic-require
6873 const appPkg = require ( path . join ( defaultAppPath , 'package.json' ) ) ;
6974 const libName = appPkg . name ;
7075 const libDesc = appPkg . description ;
@@ -362,22 +367,32 @@ module.exports = (env, argv) => {
362367 // new CssMinimizerPlugin(),
363368 ] ,
364369 } ,
370+ snapshot : {
371+ managedPaths : customResolveAliasRegex ? [
372+ customResolveAliasRegex ,
373+ ] : undefined ,
374+ } ,
365375 resolve : {
366376 extensions : [ '.tsx' , '.ts' , '.js' ] ,
377+ // By default, always search for modules in the relative node_modules. However,
378+ // if the package can not be found, fall back to the workspace node_modules. This is
379+ // useful when using the resolveAliases to resolve a package to somewhere else.
380+ modules : [ 'node_modules' , path . join ( workspacePath , 'node_modules' ) ] ,
367381 alias : Object . assign (
368382 {
369383 // Alias to jsx-runtime required as only React@18 has this export, otherwise it fails with "The request 'react/jsx-runtime' failed to resolve only because it was resolved as fully specified".
370384 // See https://github.com/facebook/react/issues/20235 for details.
371385 'react/jsx-runtime' : 'react/jsx-runtime.js' ,
372386 'react/jsx-dev-runtime' : 'react/jsx-dev-runtime.js' ,
387+ ...resolveAliases ,
373388 } ,
374389 // Add aliases for all the workspace repos
375390 ...( ! isSingleRepoMode
376391 ? workspaceRepos . map ( ( repo ) => ( {
377392 // Rewrite all '<repo>/dist' imports to '<repo>/src'
378- [ `${ repo } /dist` ] : path . join ( workspacePath , repo , 'src' ) ,
379- [ `${ repo } /src` ] : path . join ( workspacePath , repo , 'src' ) ,
380- [ `${ repo } ` ] : path . join ( workspacePath , repo , 'src' ) ,
393+ [ `${ workspaceRepoToName [ repo ] } /dist` ] : path . join ( workspacePath , repo , 'src' ) ,
394+ [ `${ workspaceRepoToName [ repo ] } /src` ] : path . join ( workspacePath , repo , 'src' ) ,
395+ [ `${ workspaceRepoToName [ repo ] } ` ] : path . join ( workspacePath , repo , 'src' ) ,
381396 } ) )
382397 : [
383398 {
@@ -398,7 +413,7 @@ module.exports = (env, argv) => {
398413 // Handle node_modules packages that contain sourcemaps
399414 shouldUseSourceMap && {
400415 enforce : 'pre' ,
401- exclude : / @ b a b e l (?: \/ | \\ { 1 , 2 } ) r u n t i m e / ,
416+ exclude : [ / @ b a b e l (?: \/ | \\ { 1 , 2 } ) r u n t i m e / , customResolveAliasRegex ] . filter ( Boolean ) ,
402417 test : / \. ( j s | m j s | j s x | t s | t s x | c s s ) $ / ,
403418 loader : require . resolve ( 'source-map-loader' ) ,
404419 } ,
@@ -444,7 +459,7 @@ module.exports = (env, argv) => {
444459 // The preset includes JSX, Flow, TypeScript, and some ESnext features.
445460 {
446461 test : / \. ( j s | m j s | j s x | t s | t s x ) $ / ,
447- exclude : / n o d e _ m o d u l e s / ,
462+ exclude : [ / n o d e _ m o d u l e s / , customResolveAliasRegex ] . filter ( Boolean ) ,
448463 loader : 'babel-loader' ,
449464 options : {
450465 presets : [ [ '@babel/preset-env' , { targets : { browsers : 'last 2 Chrome versions' } } ] , '@babel/preset-typescript' , '@babel/preset-react' ] ,
@@ -688,10 +703,11 @@ module.exports = (env, argv) => {
688703 incremental : true ,
689704 paths : Object . assign (
690705 { } ,
706+ resolveAliases ,
691707 ...( ! isSingleRepoMode
692708 ? workspaceRepos . map ( ( r ) => ( {
693- [ `${ r } /dist` ] : [ path . join ( workspacePath , r , 'src/*' ) ] ,
694- [ r ] : [ path . join ( workspacePath , r , 'src/index.ts' ) ] ,
709+ [ `${ workspaceRepoToName [ r ] } /dist` ] : [ path . join ( workspacePath , r , 'src/*' ) ] ,
710+ [ workspaceRepoToName [ r ] ] : [ path . join ( workspacePath , r , 'src/index.ts' ) ] ,
695711 } ) )
696712 : [
697713 {
0 commit comments