forked from nrwl/nx
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(react): migrate webpack config (nrwl#14663)
- Loading branch information
Showing
7 changed files
with
409 additions
and
11 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
57 changes: 57 additions & 0 deletions
57
packages/react/src/migrations/update-15-6-3/__snapshots__/webpack-config-setup.spec.ts.snap
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
// Jest Snapshot v1, https://goo.gl/fbAQLP | ||
|
||
exports[`15.6.3 migration (setup webpack.config file for React apps) should create webpack.config.js for React projects only 1`] = ` | ||
" | ||
const { composePlugins, withNx } = require('@nrwl/webpack'); | ||
const { withReact } = require('@nrwl/react'); | ||
// Nx plugins for webpack. | ||
module.exports = composePlugins(withNx(), withReact(), (config, { options, context }) => { | ||
// Update the webpack config as needed here. | ||
// e.g. config.plugins.push(new MyPlugin()) | ||
return config; | ||
}); | ||
" | ||
`; | ||
|
||
exports[`15.6.3 migration (setup webpack.config file for React apps) should create webpack.config.js for React projects only 2`] = ` | ||
" | ||
const { composePlugins, withNx } = require('@nrwl/webpack'); | ||
const { withReact } = require('@nrwl/react'); | ||
// Nx plugins for webpack. | ||
module.exports = composePlugins(withNx(), withReact(), (config, { options, context }) => { | ||
// Update the webpack config as needed here. | ||
// e.g. config.plugins.push(new MyPlugin()) | ||
return config; | ||
}); | ||
" | ||
`; | ||
|
||
exports[`15.6.3 migration (setup webpack.config file for React apps) should create webpack.config.js for React projects only 3`] = ` | ||
" | ||
const { composePlugins, withNx } = require('@nrwl/webpack'); | ||
const { withReact } = require('@nrwl/react'); | ||
// Nx plugins for webpack. | ||
module.exports = composePlugins(withNx(), withReact(), (config, { options, context }) => { | ||
// Update the webpack config as needed here. | ||
// e.g. config.plugins.push(new MyPlugin()) | ||
return config; | ||
}); | ||
" | ||
`; | ||
|
||
exports[`15.6.3 migration (setup webpack.config file for React apps) should create webpack.config.js for React projects only 4`] = ` | ||
" | ||
const { composePlugins, withNx } = require('@nrwl/webpack'); | ||
const { withReact } = require('@nrwl/react'); | ||
// Nx plugins for webpack. | ||
module.exports = composePlugins(withNx(), withReact(), (config, { options, context }) => { | ||
// Note: This was added by an Nx migration. | ||
// You should consider inlining the logic into this file. | ||
return require('./webpack.something.old.ts')(config, context); | ||
}); | ||
" | ||
`; |
176 changes: 176 additions & 0 deletions
176
packages/react/src/migrations/update-15-6-3/webpack-config-setup.spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,176 @@ | ||
import { createTreeWithEmptyWorkspace } from '@nrwl/devkit/testing'; | ||
import { | ||
addProjectConfiguration, | ||
readProjectConfiguration, | ||
Tree, | ||
} from '@nrwl/devkit'; | ||
import webpackConfigSetup from './webpack-config-setup'; | ||
|
||
describe('15.6.3 migration (setup webpack.config file for React apps)', () => { | ||
let tree: Tree; | ||
|
||
beforeEach(async () => { | ||
tree = createTreeWithEmptyWorkspace({ layout: 'apps-libs' }); | ||
|
||
addProjectConfiguration(tree, 'react1', { | ||
root: 'apps/react1', | ||
targets: { | ||
build: { | ||
executor: '@nrwl/webpack:webpack', | ||
options: { | ||
main: 'apps/react1/src/main.tsx', | ||
webpackConfig: '@nrwl/react/plugins/webpack', | ||
}, | ||
}, | ||
}, | ||
}); | ||
addProjectConfiguration(tree, 'react2', { | ||
root: 'apps/react2', | ||
targets: { | ||
custom: { | ||
executor: '@nrwl/webpack:webpack', | ||
options: { | ||
main: 'apps/react2/src/main.tsx', | ||
}, | ||
}, | ||
}, | ||
}); | ||
|
||
addProjectConfiguration(tree, 'react3', { | ||
root: 'apps/react3', | ||
targets: { | ||
custom: { | ||
executor: '@nrwl/webpack:webpack', | ||
options: { | ||
webpackConfig: '@nrwl/react/plugins/webpack', | ||
}, | ||
}, | ||
}, | ||
}); | ||
|
||
addProjectConfiguration(tree, 'react4', { | ||
root: 'apps/react4', | ||
targets: { | ||
custom: { | ||
executor: '@nrwl/webpack:webpack', | ||
options: { | ||
main: 'apps/react4/src/main.tsx', | ||
webpackConfig: 'apps/react4/webpack.something.ts', | ||
}, | ||
}, | ||
}, | ||
}); | ||
tree.write('apps/react4/webpack.something.ts', 'some content'); | ||
|
||
addProjectConfiguration(tree, 'app4', { | ||
root: 'apps/app4', | ||
targets: { | ||
custom: { | ||
executor: '@nrwl/webpack:webpack', | ||
options: { | ||
webpackConfig: 'some/random/path/webpack.something.ts', | ||
}, | ||
}, | ||
}, | ||
}); | ||
|
||
tree.write('some/random/path/webpack.something.ts', 'some content'); | ||
|
||
addProjectConfiguration(tree, 'app5', { | ||
root: 'apps/app5', | ||
targets: { | ||
custom: { | ||
executor: '@nrwl/webpack:webpack', | ||
options: { | ||
isolatedConfig: true, | ||
}, | ||
}, | ||
}, | ||
}); | ||
|
||
addProjectConfiguration(tree, 'app6', { | ||
root: 'apps/app6', | ||
targets: { | ||
build: { | ||
executor: '@nrwl/webpack:webpack', | ||
options: { | ||
main: 'apps/app6/src/main.ts', | ||
}, | ||
}, | ||
}, | ||
}); | ||
|
||
await webpackConfigSetup(tree); | ||
}); | ||
|
||
it('should create webpack.config.js for React projects only', () => { | ||
expect( | ||
tree.read('apps/react1/webpack.config.js', 'utf-8') | ||
).toMatchSnapshot(); | ||
expect( | ||
tree.read('apps/react2/webpack.config.js', 'utf-8') | ||
).toMatchSnapshot(); | ||
expect( | ||
tree.read('apps/react3/webpack.config.js', 'utf-8') | ||
).toMatchSnapshot(); | ||
|
||
expect( | ||
tree.read('apps/react4/webpack.something.ts', 'utf-8') | ||
).toMatchSnapshot(); | ||
|
||
expect( | ||
tree.read('apps/react4/webpack.something.old.ts', 'utf-8') | ||
).toMatchInlineSnapshot(`"some content"`); | ||
}); | ||
|
||
it('should ignore non-react projects or isolatedConfig', () => { | ||
expect( | ||
tree.read('some/random/path/webpack.something.ts', 'utf-8') | ||
).toMatchInlineSnapshot(`"some content"`); | ||
expect( | ||
tree.exists('some/random/path/webpack.something.old.ts') | ||
).toBeFalsy(); | ||
expect(tree.exists('apps/app5/webpack.config.js')).toBeFalsy(); | ||
expect(tree.exists('apps/app6/webpack.config.js')).toBeFalsy(); | ||
}); | ||
|
||
it('should update the project configuration - executor options', () => { | ||
expect( | ||
readProjectConfiguration(tree, 'react1').targets.build.options | ||
.webpackConfig | ||
).toBe('apps/react1/webpack.config.js'); | ||
expect( | ||
readProjectConfiguration(tree, 'react2').targets.custom.options | ||
.webpackConfig | ||
).toBe('apps/react2/webpack.config.js'); | ||
|
||
expect( | ||
readProjectConfiguration(tree, 'react3').targets.custom.options | ||
.webpackConfig | ||
).toBe('apps/react3/webpack.config.js'); | ||
|
||
expect( | ||
readProjectConfiguration(tree, 'react4').targets.custom.options | ||
.webpackConfig | ||
).toBe('apps/react4/webpack.something.ts'); | ||
|
||
expect( | ||
readProjectConfiguration(tree, 'react1').targets.build.options | ||
.isolatedConfig | ||
).toBeTruthy(); | ||
expect( | ||
readProjectConfiguration(tree, 'react2').targets.custom.options | ||
.isolatedConfig | ||
).toBeTruthy(); | ||
|
||
expect( | ||
readProjectConfiguration(tree, 'react3').targets.custom.options | ||
.isolatedConfig | ||
).toBeTruthy(); | ||
|
||
expect( | ||
readProjectConfiguration(tree, 'react4').targets.custom.options | ||
.isolatedConfig | ||
).toBeTruthy(); | ||
}); | ||
}); |
128 changes: 128 additions & 0 deletions
128
packages/react/src/migrations/update-15-6-3/webpack-config-setup.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,128 @@ | ||
import { | ||
formatFiles, | ||
logger, | ||
readProjectConfiguration, | ||
Tree, | ||
updateProjectConfiguration, | ||
} from '@nrwl/devkit'; | ||
import { forEachExecutorOptions } from '@nrwl/workspace/src/utilities/executor-options-utils'; | ||
import { basename } from 'path'; | ||
|
||
export default async function (tree: Tree) { | ||
forEachExecutorOptions( | ||
tree, | ||
'@nrwl/webpack:webpack', | ||
(options: {}, projectName, targetName, _configurationName) => { | ||
// If isolatedConfig is set, we don't need to do anything | ||
// If it is NOT React, we don't need to do anything | ||
if ( | ||
options?.['isolatedConfig'] || | ||
!( | ||
options?.['main']?.match(/main\.(t|j)sx$/) || | ||
options?.['webpackConfig'] === '@nrwl/react/plugins/webpack' | ||
) | ||
) { | ||
return; | ||
} | ||
|
||
// If webpackConfig is set, update it with the new options | ||
// If webpackConfig is not set, we need to create a new | ||
// webpack.config.js file and set the path to it in the | ||
// executor options | ||
|
||
if ( | ||
options?.['webpackConfig'] && | ||
options['webpackConfig'] !== '@nrwl/react/plugins/webpack' | ||
) { | ||
let oldName = options['webpackConfig']; | ||
if (options['webpackConfig'].endsWith('.js')) { | ||
oldName = options['webpackConfig'].replace('.js', '.old.js'); | ||
} | ||
if (options['webpackConfig'].endsWith('.ts')) { | ||
oldName = options['webpackConfig'].replace('.ts', '.old.ts'); | ||
} | ||
|
||
renameFile(tree, options['webpackConfig'], oldName); | ||
|
||
const justTheFileName = basename(oldName); | ||
tree.write( | ||
options['webpackConfig'], | ||
` | ||
const { composePlugins, withNx } = require('@nrwl/webpack'); | ||
const { withReact } = require('@nrwl/react'); | ||
// Nx plugins for webpack. | ||
module.exports = composePlugins(withNx(), withReact(), (config, { options, context }) => { | ||
// Note: This was added by an Nx migration. | ||
// You should consider inlining the logic into this file. | ||
return require('./${justTheFileName}')(config, context); | ||
}); | ||
` | ||
); | ||
|
||
options['isolatedConfig'] = true; | ||
|
||
const projectConfiguration = readProjectConfiguration( | ||
tree, | ||
projectName | ||
); | ||
projectConfiguration.targets[targetName].options = options; | ||
updateProjectConfiguration(tree, projectName, projectConfiguration); | ||
|
||
logger.info( | ||
` | ||
${options['webpackConfig']} has been renamed to ${oldName} and a new ${options['webpackConfig']} | ||
has been created for your project ${projectName}. | ||
You should consider inlining the logic from ${oldName} into ${options['webpackConfig']}. | ||
You can read our guide on how to do this here: | ||
https://nx.dev/packages/webpack/documents/webpack-config-setup | ||
` | ||
); | ||
} else { | ||
const projectConfiguration = readProjectConfiguration( | ||
tree, | ||
projectName | ||
); | ||
|
||
if (!options) { | ||
options = {}; | ||
} | ||
|
||
options[ | ||
'webpackConfig' | ||
] = `${projectConfiguration.root}/webpack.config.js`; | ||
options['isolatedConfig'] = true; | ||
|
||
tree.write( | ||
options['webpackConfig'], | ||
` | ||
const { composePlugins, withNx } = require('@nrwl/webpack'); | ||
const { withReact } = require('@nrwl/react'); | ||
// Nx plugins for webpack. | ||
module.exports = composePlugins(withNx(), withReact(), (config, { options, context }) => { | ||
// Update the webpack config as needed here. | ||
// e.g. config.plugins.push(new MyPlugin()) | ||
return config; | ||
}); | ||
` | ||
); | ||
|
||
projectConfiguration.targets[targetName].options = options; | ||
updateProjectConfiguration(tree, projectName, projectConfiguration); | ||
} | ||
} | ||
); | ||
|
||
await formatFiles(tree); | ||
} | ||
|
||
function renameFile(tree: Tree, from: string, to: string) { | ||
const buffer = tree.read(from); | ||
if (!buffer) { | ||
return; | ||
} | ||
tree.write(to, buffer); | ||
tree.delete(from); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.