I can run the nx build command without npm installing styled-components package.
What is the current behavior?
After upgrading from nx 9.0.0 to nx 9.2.2, I can't build my react app. I get the following msg
ERROR in ./app/App.jsx
Module not found: Error: Can't resolve 'styled-components' in 'foo/apps/bar/src/app'
We use emotion and never relied on styled-components.
When I npm installed styled-components, then the build command works again.
Please provide detailed steps for reproducing the issue.
update to 9.2.2 and run nx build <appname>
i think this might be related to this PR https://github.com/nrwl/nx/pull/2605
We have found a related issue where #2605 definitely adds a regression to our app. Our app no longer detects emotion and tries to use styled-components instead. We've been able to work around this issue by removing the plugins added here (https://github.com/nrwl/nx/commit/5cdf372#diff-e48573255298e2cfadc0bc36491a5ed2R11) from our custom webpack config.
I ran into this issue, too, and also had to use a custom webpack config to remove the plugins. In my app, I noticed that styled-components code was actually making it into the bundled output, even though I only use emotion.
@epikhighs Sorry about the breakage. This will be fixed in a patch release soon!
@epikhighs @brianmcd Do you happen to have a repo I can check out?
I've tried reproducing it here but the build didn't fail for me: https://github.com/jaysoo/emotion-test-922
I don't have a public repo i can share @jaysoo , but for my project, we are modifying babel-loader in our custom webpack config. So maybe the ordering of the babel plugins or babel presets maybe changes things? I noticed in your sample repo, you do not have a custom webpack config.
```
// in our custom webpack file
const { updateBabelOptions } = require('@nrwl/react/src/utils/babel-utils');
// Add React-specific configuration
function getWebpackConfig(config) {
const idx = config.module.rules.findIndex(r => r.loader === 'babel-loader');
const babelRuleOptions = config.module.rules[idx].options;
babelRuleOptions.presets.push('@emotion/babel-preset-css-prop');
babelRuleOptions.plugins.push(['import', {libraryName: 'antd'}]); // babel-plugin-import
updateBabelOptions(babelRuleOptions);
// remove problematic plugins manually
babelRuleOptions.plugins = babelRuleOptions.plugins.filter(x => {
if (typeof x === 'string' && x.indexOf('babel-plugin-emotion') >= 0) {
return false;
} else if (Array.isArray(x) && x[0].indexOf('babel-plugin-styled-components') >= 0) {
return false;
}
return true;
});
...
}```
@jaysoo - Thanks for looking into this.
Here's a repo: https://github.com/brianmcd/nx-emotion-bug. I generated the project with the latest Nx and made the changes in app.tsx.
I think using emotion's css prop instead of its styled API is triggering the behavior (https://emotion.sh/docs/css-prop#jsx-pragma).
Trying to build the project as-is results in: Module not found: Error: Can't resolve 'styled-components'. If you actually install styled-components in that repo, you'll see this in the bundled output, even though the code isn't using styled-components:
/* harmony import */ var styled_components__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! styled-components */ "../../../node_modules/styled-components/dist/styled-components.browser.esm.js");
In my real project, I spliced out babel-plugin-styled-components and it fixed it for me:
function removeStyledComponentsPlugin(nxConfig) {
const options = getBabelLoaderOptions(nxConfig);
const idx = options.plugins.findIndex((p) => {
return Array.isArray(p) && p[0].includes('babel-plugin-styled-components');
});
if (idx === -1) {
throw new Error();
}
options.plugins.splice(idx, 1);
}
function getBabelLoaderOptions(config) {
const idx = config.module.rules.findIndex((r) => r.loader === 'babel-loader');
if (idx === -1) {
throw new Error();
}
return config.module.rules[idx].options;
}
@brianmcd Thanks! I guess my tests didn't have use the right API to cause breakages. I'm going to look at adding in the styled-component and emotion specific plugins (for SSR) only if they are used.
This will be patched in the next version. Moving beyond that, I think we should actually generate the .babelrc for each project so overriding options is more straighforward.
Thanks a ton, @jaysoo!
Most helpful comment
This will be patched in the next version. Moving beyond that, I think we should actually generate the
.babelrcfor each project so overriding options is more straighforward.