
Show HN: Single-file components for React - MunGell
https://github.com/digitalie/one-loader
======
MunGell
I am using Vue and React on a couple of projects and found it convenient to
have Vue components contained in a single file.

As an experiment, I've created a Webpack loader to allow combining styling and
React code in a single file.

This is not production-ready and could be redundant for inline-styled
components (in its current state anyways).

Feedback is welcome.

------
tlb
I really need syntax highlighting and tab-completion within CSS, because CSS
and I don't have a mutual understanding. Atom does this natively within .css
files -- is it easy to make it work for JSX-embedded stylesheets?

~~~
btown
See syntax highlighting section here: [https://github.com/zeit/styled-
jsx/blob/master/readme.md](https://github.com/zeit/styled-
jsx/blob/master/readme.md)

------
peternicky
Upvoted because I like experimentation however I still cannot think of a
reason to structure react components in this style. Is this more of an
exercise to port an idea you like from Vue into React?

~~~
MunGell
I liked the idea of how Vue components combine business logic and styling code
in one file using HTML-like wrappers.

As I mentioned in a comment below I realise there is already a number of ways
to approach the problem. I personally didn't find any of the ones that I am
aware of being as convenient, so I've created and published this experimental
loader to see if it 1. would actually work for React and 2. if someone else
finds this concept interesting/convenient.

------
spankalee
Another example of why we need HTML Modules:
[https://github.com/w3c/webcomponents/issues/645](https://github.com/w3c/webcomponents/issues/645)

------
devdad
Not to be rude, but I fail to see what the use case is for this. You can
already use CSS in React and a component is often CSS, JS and JSX. What's the
win here?

~~~
MunGell
Hi @devdad,

Thanks for your feedback!

I guess you mean CSS-in-JS approaches where CSS is either put inside JS code
as a template literals/string (styled-components, csjs etc) or as inline
styles with JS objects (Radium etc.). Both approaches have their own
advantages and disadvantages.

It could be only me, but I personally don't like the idea of having inline
styles, although I realise it could be the only way to make styles cross-
platform.

The string approach works well and has additional advantage of dynamic
property values (in case of template literals). However, (and this is IMHO
again), I can't say this is the most readable way to structure code,
especially if you rely on IDE/text editor identifying this code as CSS.

There is a third approach, which is basically putting <style> tag right in JSX
component, but this then gets repeated with every component you put on the
page. Thus, I wouldn't consider this as an approach at all.

Let me know if I missed anything above.

My initial intention was to create a way to get styling and JS/JSX code
together in one file in a way that would keep code readable and reusable.

This experiment does not tick all the boxes for the cross-platform, easy to
write and read reusable way of combining styles and JS code in one file.
However, the concept could be convenient in some cases where cross-platform-
ness is not a requirement and styles are already written in CSS.

As I mentioned, one-loader was inspired by vue-loader, which I found
convenient for the purpose of storing css and js code in one file.

Hope that makes sense

~~~
akawry
What about just importing the css file from your component file?

For example, in MyComponent.js, you have:

    
    
      import './MyComponent.css';
      
      const MyComponent = () => (
        <div className="my-class">I'm a component!</div>
      );
    

and in MyComponent.css,

    
    
      .my-class {
        color: red;
      }
    

To handle proper scoping, you could use something like css-modules or wrap
each component in a top-level <div> with a component-specific class name. For
example:

    
    
      const MyComponent = () => (
        <div className="MyComponent">
          <div className="content">
             I'm a component
          </div>
        </div>
      );
    

and then

    
    
      .MyComponent.content {
        color: red;
      }
    

If you use a preprocessor like sass, you can just nest your entire component-
specific styles like this:

    
    
      .MyComponent
        .content
          color: red
        .footer
          color: blue

~~~
MunGell
I use this approach in most cases combining it with BEM class naming. However,
the point of having single-file components it to have all the required code in
one file, including CSS/styling.

------
spraak
For a similar but more comprehensive approach, try zeit/next

