Closed brauliodiez closed 7 years ago
My two cents: I would choose CSS-Modules.
Thanks for the feedback @franmolmedo , the approach could be?
Do you agree?
That´s right. We need to update webpack configuration adding a new loader that makes the trick. Besides that, developers don´t have to be worried about naming and collisions because this loader assings an unique identifier to each component and then prepends this identifier to all styles related.
Is this loader a good one to give a try?
https://github.com/gajus/react-css-modules
Not sure if maybe @linuxonrails would like to give a try on this case :).
The common css loaders also works https://github.com/webpack/css-loader, but the configuration changes a bit, something like: test: /.(scss|sass)$/, loaders: ['style', 'css?modules&importLoaders=1', 'postcss', 'sass'],
Also it has to be updated in test configuration if we want to test if certain styles are applied to a component in concrete circunstances.
That's true, we have to evaluate which o both fits best our needs.
An example with css-modules (I had some issues with typescript):
https://github.com/linuxonrails/react-by-sample/tree/cssmodules/16%20CSSModules
Cool stuff !!! @nasdan @franolmedo @jaimesalas what do you think?
What about having a common SASs file with the theming colores?
On my humble opinion, I think right now that is our best choice, since I discuss with @brauliodiez the issues that comes with CSS Module. Looks like loads of fun ;)
CSS Modules has too many problems with TypeScript:
You need generate typings of each css file (very slow). And reopen Atom editor because it doesn't refresh typings when the file is open in a tab.
If you have an error in stylesheet file the typings file is not generated (but you will not know why: no console errors).
Example A:
.table {
composes: table from './table.css';
}
.row {
composes: row from './table.css';
}
.table {
width: 400px;
}
Problem? The .table
selector is repeated.
Example B:
.table-foobar {
color: red;
}
Problem? table-foobar
is not a valid variable name.
Example C:
.table {
composes: table from './fileNotExists.css';
}
Problem? Yes. No errors in atom but... typings will not be generated. Another silent error. https://github.com/gajus/react-css-modules#extending-component-styles
And...
another problem in JSX code!!
import * as React from 'react';
import CSSModules from 'react-css-modules';
import * as styles from './foobar.css'; // .foobar { color: red }
class Foobar extends React.Component<{}, {}> {
render () {
return <div styleName='foobar'>
This text should be red!
</div>;
}
}
export default CSSModules(Foobar, styles);
react-css-modules require overwrite render() method.
export { CSSModules(Foobar, styles) }
doesn't work m-( It works only with default export.
And I think it is ugly to add that code in each file.
...but we can use ES7 decorators:
import * as React from 'react';
import CSSModules from 'react-css-modules';
import * as styles from './foobar.css'; // .foobar { color: red }
@CSSModules(styles)
export class Foobar extends React.Component<{}, {}> {
render () {
return <div styleName='foobar'>
This text should be red!
</div>;
}
}
...but TypeScript has an experimental support for decorators:
(6,14): error TS1219: Experimental support for decorators is a feature that is subject to change in a future release. Set the 'experimentalDecorators' option to remove this warning.
I will continue investigating...
lol
<--- Last few GCs --->
[9846:0xa7cfb80] 546246 ms: Mark-sweep 700.6 (803.2) -> 700.6 (803.2) MB, 3165.3 / 0.0 ms (+ 1.3 ms in 3 steps since start of marking, biggest step 1.3 ms) allocation failure GC in old space requested [9846:0xa7cfb80] 549173 ms: Mark-sweep 700.6 (803.2) -> 700.6 (802.2) MB, 2925.8 / 0.0 ms (+ 1.3 ms in 1 steps since start of marking, biggest step 1.3 ms) last resort gc [9846:0xa7cfb80] 551798 ms: Mark-sweep 700.6 (802.2) -> 700.6 (802.2) MB, 2624.4 / 0.0 ms last resort gc
<--- JS stacktrace --->
==== JS stack trace =========================================
Security context: 0x2f9739dd
FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory
1: node::Abort() [node]
2: 0x8e56266 [node]
3: v8::Utils::ReportOOMFailure(char const, bool) [node]
4: v8::internal::V8::FatalProcessOutOfMemory(char const, bool) [node]
5: v8::internal::Factory::NewRawOneByteString(int, v8::internal::PretenureFlag) [node]
6: v8::internal::String::SlowFlatten(v8::internal::Handle
Have you tried using requiere instead of import?
Maybe we loose some intellisense.but it.could work
Thanks @brauliodiez !
Another option to generate typings on-the-fly: https://github.com/Jimdo/typings-for-css-modules-loader
It's works with require in a test case:
import * as React from 'react';
const css = require('react-css-modules');
const styles = require('./table.css');
@css(styles)
class Table extends React.Component<{}, {}> {
render() {
return (
<div styleName='foobar'>
This should be in red color!
</div>
);
}
}
export { Table };
But the next line in tsconfig.json:
"types": ["karma-chai-sinon"]
throws an error in TS:
ERROR in ./table.tsx (9,12): error TS2339: Property 'styleName' does not exist on type 'HTMLProps
'.
I will work in other issues the next days :-(
No prob, I will take a look, we will end up with some stuff :).
Give me a buzz if you run out of issues, I have some more pending to define :).
Good work, going to reassign this issue to @Nasdan he will do some further research. He will buzz us whenever there is any update.
I've create an issue #57 to implement it.
A quick heads up, CSS Modules does not support nested selectors:
https://github.com/css-modules/css-modules/issues/131
Since we are developers we can live without this, but if we ask a designer to work on this probably he will start complaining about this.
Inside the same css it will work fine, the issue come, when, for instance you want style children elements that are below a bootstrap 'well'.
What's your take on this? @Nasdan @franmolmedo @linuxonrails
We are evaluating TypeStyle:
https://github.com/typestyle/typestyle
Const: going to full typescript way.
Pros: Support all the CSS stuff + you get intellisense + js support + lazy loading
Gray areas: Now it generates random unique names, we have to check whether there is a way to add basename + prefix?
Failing case:
.pageError404 {
margin-top: 6em;
}
.pageError404 .panel {
background-color: blue;
}
import * as React from 'react';
import {pageError404} from './styles.css';
export const NotFoundPage = () => {
return (
<div className={`row ${pageError404}`}>
<div className="col-md-8 col-md-offset-2">
<div className="panel panel-danger">
</div>
</div>
</div>
);
}
About SASS import duplicate (first let's check if sass-loader in fact generate duplicates or not), it seems that there are workarounds available (node-sass-import-once).
https://github.com/at-import/node-sass-import-once
http://stackoverflow.com/questions/36926521/webpack-sass-loader-cannot-dedupe-common-scss-imports
I can speak only if working with ES6: This way the example works:
master.sass
@import "../../content/variables.sass"
.main
border: 2px solid $master-border-color
color: $basic-font-color
.test
background-color: red
color: green
&:hover
background-color:blue !important
cursor: pointer`
master.js
import React, { Component } from 'react';
import masterStyles from './master.sass';
class Master extends Component {
render() {
return (
<div className={ masterStyles.main }>
Master page
<div className={ masterStyles.test }> HELLO </div>
</div>
);
}
}
export { Master };
On the other way, we can check if any postcss action can satisfy all our needs.
And about double imports: no content duplicated in the bundled styles.css at least using variables.sass as global variables resources.
It is not about duplicate, it is about that you brought all the file (if you import varibles.sass, you bring all the variable), instead you have a .ts file, you can import just the staff that you want. That is the key difference. I do not really know, if there is a way to do that wit sass, but feels natural to be done with TypeStyle
I don´t get it. As far i know imports in sass or less are everything or nothing. Another idea is not using a big global variables files and use small files to import in. Using typestyle is another option. I haven´t yet used it in a real environment. No comments though
@franmolmedo is right, my fault, dummy mistake, no matter how many times your import your SASS it will get converted just to CSS. I think right now we should go for CSS Modules, and play in a lab with typescript css experiment. @nasdan can you setup this and ask for PR, we have a nice progress bar component made by @rumbado waiting for css modules love :).
There is a PR #67 with all SASS and CSS Modules stuff
Closing thia issue, CSS modules approach os on máster, se Will hace some fin un the future when creating component libraries but that's a.separate issue
As @franmolmedo mentioned, there is an open area here, we need to discuss and choose which approach to follow when handling styles:
Moving to SASS seems to be a good decisition (we will need to define some common variables, colors etc... discussion and further definition needed here).
BEM: Should we use this "nomenclature", if we jump into CSS Modules maybe not.
CSS Modules: seems to be the cool kid in town, it's worth to use it, can we have drawbacks using this approach?
@red your input is really appreciated here as well.