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

How to use external libraries #109

Closed
sarink opened this Issue Feb 2, 2016 · 10 comments

Comments

Projects
None yet
9 participants
@sarink

sarink commented Feb 2, 2016

I am working on a project that uses css-modules and am consistently being faced with this problem:

We want to use some library that renders a React component.

This library will render some markup like

<div class='foo'>
  <div class='bar'> </div>
</div>

Now, how am I supposed to style the foo and bar classes?

So far, the best I've come up with is...
Build a wrapper component which wraps the foo div in <div styleName="myWrapper">, then write some css like

.myWrapper {
  :global {
    // copy-and-paste all the css from whatever library, because you can't `@import` anything inside of a :global selector

    .bar {
      // apply any overrides, but remember, since you're nested, you can't `compose` anything
    }
  }
}

Is there a better way to do this? Having such poor support for existing libraries is making css-modules really difficult to use.

@StevenIseki

This comment has been minimized.

Contributor

StevenIseki commented Feb 5, 2016

Hi @sarink in my opinion if the global css modules you are trying to import can be re-used as a general css module by many componets, you should publish them to npm. This way you can easily import the module and use it in your components.

I have a few examples of this:

@sarink

This comment has been minimized.

sarink commented Feb 6, 2016

@StevenIseki That's a nice solution, but it's just not very feasible or realistic. There are thousands of libraries out there, building and maintaing a css-modules-compatible fork of each one is ridiculous.

@StevenIseki

This comment has been minimized.

Contributor

StevenIseki commented Feb 6, 2016

all they really need to do is add a package.json and npm publish the module. So it doesn't seem too difficult to me.

@sohkai

This comment has been minimized.

sohkai commented Feb 22, 2016

@sarink I'm having trouble with something similar, trying to use React-Bootstrap (or rather, make sure that it still works afterwards), bootstrap, and CSS Modules. @StevenIseki's done some great work with bootstrap-css but unfortunately if other libraries, ie. React-Bootstrap, rely on the global class names, they won't work anymore.

What I've settled on for now, is just to load the external library's CSS as-is, without any CSS Modules modifications, and then if I need to compose a style from it, I use `composes: foo from global'. If you can load the external CSS, you shouldn't need to copy over the styles, and since I assume it's out of your hands, there's no benefit in you modularizing the library's CSS.

As for overriding styles, this seems to be more of a component design issue than with CSS Modules (due to it's limitations; see #33). If you can modify the library, can you add a className parameter or additional theme extensions? If you can't, then you can either make wrapper components like what you've been doing, or use a global stylesheet whose sole purpose is to apply overrides for the library. Since I'm working with React-Bootstrap, I supply my overrides either through components' bsClass properties in wrapper components or add styles to a global stylesheet that supplies default overrides for bootstrap. To enable global theme changes, I use rethemable.

@themitchy

This comment has been minimized.

themitchy commented Feb 25, 2016

We hit some similar issues and solved it with @import. Check out #65, there are a few other solutions there as well.

@jdelafon

This comment has been minimized.

jdelafon commented Oct 27, 2016

I ran many times through the issues mentioned above and still don't understand what the solution is to overriding a class name from an external component (loading external libraries is ok). Can somebody please suggest something understandable? (Unlike "I used @import and it worked").

I have a grid with deeply nested components and apparently my loader does not understand nested css (which I never needed until now).

@dvkndn

This comment has been minimized.

dvkndn commented Oct 27, 2016

@jdelafon I used @import and it worked. Detail: #65 (comment)

@outdooricon

This comment has been minimized.

outdooricon commented Nov 3, 2016

to be clear, @import will not work if you are using sass because sass will inline the content. So you will either need to wrap the import in :global or import the css your component js instead using the !style!css prefix to skip the module call.

@TrySound

This comment has been minimized.

Member

TrySound commented May 31, 2017

See #147

@TrySound TrySound closed this May 31, 2017

@kricore

This comment has been minimized.

kricore commented Aug 16, 2017

Sorry to hijack. This is a crude solution, but if you just want to prototype your app or looking for something quick and dirty it might do the trick.

       {
            test: /(\.bootstrap\.css$|bootstrap-theme.css|bootstrap.css)/,
            use: [
                {
                    loader: 'style-loader',
                },
                {
                    loader: 'css-loader',
                    options: {
                        minimize: true || {/* CSSNano Options */}
                    }
                },
            ],
        },
        {
            test: /^((?!\.bootstrap|bootstrap-theme).)*\.css$/,
            use: [
                {
                    loader: 'style-loader',
                },
                {
                    loader: 'css-loader?modules&importLoaders=1&localIdentName=[name]__[local]___[hash:base64:5]',
                },
                {
                    loader: require.resolve('postcss-loader'),
                    options: {
                        // Necessary for external CSS imports to work
                        // https://github.com/facebookincubator/create-react-app/issues/2677
                        ident: 'postcss',
                        plugins: () => [
                            require('postcss-flexbugs-fixes'),
                            autoprefixer({
                                browsers: [
                                    '>1%',
                                    'last 4 versions',
                                    'Firefox ESR',
                                    'not ie < 9', // React doesn't support IE8 anyway
                                ],
                                flexbox: 'no-2009',
                            }),
                        ],
                    },
                }
            ]
        },

https://gist.github.com/kricore/505c14fb9c69d77184458499707c2d98

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment