-
-
Notifications
You must be signed in to change notification settings - Fork 9.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support css-modules #4405
Support css-modules #4405
Conversation
Codecov Report
@@ Coverage Diff @@
## master #4405 +/- ##
=========================================
- Coverage 35.91% 35.7% -0.22%
=========================================
Files 555 557 +2
Lines 6668 6708 +40
Branches 871 879 +8
=========================================
Hits 2395 2395
- Misses 3826 3858 +32
- Partials 447 455 +8
Continue to review full report at Codecov.
|
Awesome work @chadfawcett 🎈 |
@chadfawcett love the change! Would this be better isolated in the examples rather than supported at the core level? |
@gabrielcsapo if it was isolated at the example level, wouldn’t that mean it was an end user override similar to the workaround proposed in the original issue? |
@chadfawcett is correct here. I think the best approach would be to narrow this into a preset specific for either React of CRA. I'm sure @igor-dv will be able to help with this. |
I’ve got a fairly good idea of how to implement the preset, but it’s a lot more work to merge the default and cra configs. So I thought I’d propose this solution first 😜 |
I fear this will not work well with other frameworks. |
@ndelangen Would it cause anymore issues with other frameworks than the existing |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we need to be very careful with the changes like this since you are adding it to the default webpack config and it may really break other usages/frameworks without the real benefit to them. Also, the convention of file.module.css
- I am not sure how much this is common (for example I don't use it =). So, who is really winning from this change?
I’ve got a fairly good idea of how to implement the preset, but it’s a lot more work to merge the default and cra configs
Integration with CRA is acutaly the thing we need to do 🤷♂️ . Also, I assume we do not need to merge the full config, but only styling, at least for now IMO (I didn't see any other issues that are not related to styling).
P.S sorry for being unresponsive, I am returning from the vacation tomorrow =)
@igor-dv Okay so it seems the consensus is that updating the default config directly is bad, and we should use a preset. There are two approaches we could take:
For reference, I figured #4298 could also be fixed if we merged more than just the style rules. Thoughts? |
I vote for 1 =) Anything neede to be merged should be merged |
Would be cool if we'd load the actual webpack config CRA uses, and merge the relevant bits |
I agree 1 is the way to go |
Why? CSS Modules are completely framework agnostic and has no direct connection with React |
@Hypnosphi you're 100% correct as always. But long term we want to move all these things into presets right? |
@Hypnosphi @ndelangen That's what I thought. It may not be the best implementation, but it's and easy win that shouldn't cause issue with anything else. Should I update the regex to support sass/scss and then call this PR done? Leave the CRA preset to a later PR? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
😍
"react-dev-utils": "^6.0.5" | ||
"react-dev-utils": "^6.0.5", | ||
"semver": "^5.6.0", | ||
"webpack": "^4.21.0" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🤔 I wonder if we could make Webpack 4+ a peer dep instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
const plugins = [...baseConfig.plugins]; | ||
if (baseConfig.mode === 'production') | ||
plugins.push( | ||
new MiniCssExtractPlugin({ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this exclude interop for CRAv1? I don't really care about that, but it could be something to consider.
} | ||
} | ||
|
||
export function getStyleRules(rules) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd love to get some comments throughout this function. Not certain what's occurring.
It looks like a way to concatenate across the subset of style loading possibilities given the array of file suffixes we're sifting?
|
||
export function applyCRAWebpackConfig(baseConfig) { | ||
// Remove style rules from baseConfig | ||
const baseRulesExcludingStyles = baseConfig.module.rules.filter( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very nice 👏
app/react/src/server/cra_config.js
Outdated
const craWebpackConfig = getCraWebpackConfig(baseConfig.mode); | ||
|
||
// Concat will ensure rules is an array | ||
const craStyleRules = getStyleRules([].concat(craWebpackConfig.module.rules)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could we not simply do:
[ ...craWebpackConfig.module.rules ]
Interested to hear more on "ensur[ing] rules is an array"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Whoops. I was thinking module.rules
could be something other than an array. This is the case for rule.test (array, regex, function, string, etc) but not the case for module.rules
. I've removed the concat statement.
const plugins = [...baseConfig.plugins]; | ||
if (baseConfig.mode === 'production') | ||
plugins.push( | ||
new MiniCssExtractPlugin({ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FWIW we dont really need autoprefixer in the default ruleset either 🤷♂️
I'm a fan of good defaults 👍
(This comment isn't about this PR, but a general point of discussion) I wonder if we could set ground rules and documentation about adding new ones. Most importantly, I wonder if we could give the user control in using presets thus removing the need for us to handle edge-cases. Presets can only be selected under X assumptions - otherwise, you're on your own. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now I am happy 👍
"react-dev-utils": "^6.0.5" | ||
"react-dev-utils": "^6.0.5", | ||
"semver": "^5.6.0", | ||
"webpack": "^4.21.0" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
app/react/src/server/cra_config.js
Outdated
// eslint-disable-next-line global-require, import/no-extraneous-dependencies, prefer-destructuring | ||
normalizeCondition = require('webpack/lib/RuleSet').normalizeCondition; | ||
// eslint-disable-next-line global-require, import/no-extraneous-dependencies | ||
MiniCssExtractPlugin = require('mini-css-extract-plugin'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So you can require it already in the applyCRAWebpackConfig
func and remove the state from the module (IMO Node caches imported modules, so you don't need to care about this issue).
We should, it's on my todo, at least for the maintainers,
Regarding the "selective" presets thingy, how can the API for this look like? |
Almost forgot. Do we have any CLI tests testing this setup? |
@chadfawcett @igor-dv @ndelangen would love to get this into an RC -- any chance we can merge this today? |
The CLI tests could be added after |
Sorry I was in the middle of responding to comments when GitHub started having issues yesterday. Glad my latest push synced in time. @igor-dv As for the CLI tests, all of the fixtures have React 15 as dependencies. This brought to light that I needed to test that Should the fixtures be updated to React 16? Or should additional fixtures be created? |
I think React 15 is not supported now, I am not sure how it works. But yeah, you can just create a new one. |
const plugins = [...baseConfig.plugins]; | ||
if (baseConfig.mode === 'production') { | ||
// eslint-disable-next-line global-require, import/no-extraneous-dependencies | ||
const MiniCssExtractPlugin = require('mini-css-extract-plugin'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On a second thought, I think this can make problems if 'mini-css-extract-plugin' is not installed as the root package in node_modules 🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe we need to do something like this instead ?
const miniCssExtractPlugin = craWebpackConfig.plugins.find(plugin => plugin.constructor.name === 'MiniCssExtractPlugin');
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you were right initially. Since we check to make sure react-scripts
is installed before calling applyCRAWebpackConfig
(I Just noticed this has all caps for CRA), then we know mini-css-extract-plugin
is present.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we want to use it, we have to depend on it
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we know mini-css-extract-plugin is present.
There's no guarantee that it's available in root node_modules
not in node_modules/react-scripts/node_modules
. You can never rely on npm hoisting
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like #4524 is broken now because of this
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Created #4534 to hopefully resolve this
@@ -33,12 +33,15 @@ | |||
"@babel/runtime": "^7.1.2", | |||
"@emotion/styled": "^0.10.6", | |||
"@storybook/core": "4.0.0-rc.1", | |||
"@storybook/node-logger": "^3.4.11", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It should be "4.0.0-rc.3"
Issue: Resolve #4306
What I did
Created a react webpack preset that pulls style rules from
create-react-app
's congis.*.module.css
)scss
andsass
)*.module.scss
and*.module.sass
)> The default Webpack config of Storybook is balanced for a medium-size project (specially created with Create React App) or a library.I know @ndelangen mentioned that this statement is a little outdated, but I feel this change should be okay as it shouldn't cause any harm adding css modules as is.@igor-dv I chose to propose the simpler option first, aspresets
aren't well defined yet, and I saw @ndelangen was working on separating the manager and preview webpack processes. Either of these may result in a better implementation of the CRA webpack config in the future.I can work on implementing thepresets
approach if this method is not sufficient. What are your thoughts?How to test
You can update
examples/cra-kitchen-sink
to the following in order to test (example code taken from initial reporting issue):Then run
yarn storybook
from theexamples/cra-kitchen-sink
repo and the "Welcome to React" will be red.Does this need a new example in the kitchen sink apps?
Maybe? I can add something similar to the code above if we want it committed into the repo.