React-select: Reccomended way to require CSS in webpack?

Created on 8 May 2015  路  35Comments  路  Source: JedWatson/react-select

What is the recommended way to bring in the CSS from this packaged in webpack?

Just doing require('react-select') appears to only bring in the javascript. I was able to get it working by adding require('react-select/less/default.less') or require('react-select/dist/default.css') to my javascript file.

I'm new to node packages so I'm not clear if that is by design or not.

categorquestion

Most helpful comment

This should really be included in the documentation.

All 35 comments

I use the same way...

@droberts84 can you show your webpack config

See below. Is require('react-select/dist/default.css') not necessary? I looked at package.json and the JS files it references, and didn't see any references to the CSS.

var path = require('path');
var webpack = require('webpack');
var rootPath = path.join(__dirname, '../', '../');

var config = module.exports = {
  // the base path which will be used to resolve entry points
  context: path.join(rootPath, 'frontend'),
  // the main entry point for our application's frontend JS
  entry: './javascripts/bootstrap-app',
};

config.output = {
  // this is our app/assets/javascripts directory, which is part of the Sprockets pipeline
  path: path.join(rootPath, 'app', 'assets', 'javascripts'),
  // the filename of the compiled bundle, e.g. app/assets/javascripts/bundle.js
  filename: 'bundle.js',
  // if the webpack code-splitting feature is enabled, this is the path it'll use to download bundles
  publicPath: '/assets',
  // this all related to source maps
  devtoolModuleFilenameTemplate: '[resourcePath]',
  devtoolFallbackModuleFilenameTemplate: '[resourcePath]?[hash]',
};

config.resolve = {
  // tell webpack which extensions to auto search when it resolves modules. With this,
  // you'll be able to do `require('./utils')` instead of `require('./utils.js')`
  extensions: ['', '.js', '.coffee', '.js.coffee', '.jsx'],
  root: rootPath,
  modulesDirectories: ['node_modules'],
  alias: {
    app: path.join(rootPath, 'frontend', 'javascripts'),
    components: path.join(rootPath, 'frontend', 'javascripts', 'components'),
    flux: path.join(rootPath, 'frontend', 'javascripts', 'flux'),
  }
};

config.resolveLoader = {
  root: path.join(rootPath, "node_modules")
};

config.plugins = [

];

// use jQuery from the rails gem
config.externals = {
  jquery: 'var jQuery'
};

config.module = {
  loaders: [
    { test: /\.coffee$/, loader: 'coffee-loader' },
    { test: /\.es6$/, loader: 'babel-loader' },
    { test: /\.jsx$/, loader: 'babel-loader'},
    // handle stylesheets required from node packages
    { test: /\.css$/, loader: 'style-loader!css-loader'},
    // need to load all react-infinte modules via babel since it contains es6
    { test: /\.js$/, include: path.join(rootPath, 'node_modules', 'react-infinite'), loader: 'babel-loader' },
    // expose flux instance globally as $flux... must use coffe-loader if coffee-script
    { test: path.join(rootPath, 'frontend', 'javascripts', 'flux'), loader: 'expose?$flux!coffee-loader'},
  ],
};

This should really be included in the documentation.

my less-loader is failing @import my config has

        {
            test: /\.less$/,
           loader: 'style!css!less'
       }

how exactly should we import this with webpack?

+1 styles not appearing for me without manual require as well

:+1: thanks for the tip @droberts84

Still no proper way to require the CSS. @JedWatson should we separate the CSS entirely and leave it to the user however they want to style it?

I agree that this is not clear from the documentation and should be more explicit.

+1
Had to look for issues to figure out best practices of including CSS, that's how I ended up here. Not obvious.

+1. Not a great initial experience!

I'm using webpack too and I tried doing import 'react-select/scss/default.scss'; however the styles are not getting loaded. Am I missing something?

For me it fixed doing import 'style!react-select/scss/default.scss'

This one worked for me:
require('style!css!sass!react-select/scss/default.scss');

I'm also having the styling issue. Is there an official way to resolve this? It would be greatly appreciated if the styling is mentioned in readme.

Me too, it would be nice if this was documented, I Thought I'd missed a step, so I guess I'll manually include the file like above.

This way worked for me:
require('react-select/less/default.less')
my webpack file has:
{ test: /\.less$/, loader: 'style!css!less' },

In 1.0.0, the require should be require('react-select/dist/react-select.css').

If it's not in node_modules and you've installed it with JSPM? @import "react-select/scss/default.scss" doesn't work for me, I also tried putting <link rel="stylesheet" type="text/css" href="jspm_packages/npm/[email protected]/scss/select.scss" /> in my index.html, but it doesnt work either. This really should be documented

import 'react-select/scss/default.scss'; worked for me with this in my webpack config file:

{
    test: /\.scss$/,
    loader: 'style!css!sass?outputStyle=expanded',
}

I am using the scss into my project.
I have added css like import 'style!react-select/scss/default.scss'; but it is not working because element is loading into DOM as show into below image like without any post fix. And since we are using the scss so the classes will appear like 'default_Select_EZy86IIj_D6Msr78 '. there is no chance to apply on element.
image

But when I import css using the href="https://npmcdn.com/react-select/dist/react-select.css" then it is working fine. But in this case we are bypass the scss compile.

Can any one share an idea how we use this using the scss.

Thanks
Rahul

@rahulkag
+1
Is there a way to use react-select with CSS Modules, so we don't need to move its CSS to globals?

I think component can be write that way where it will take one root selector and the rest of selector will followed by root in side it. And root selector need to apply while calling it.
So that way any component can be work with sass/less or css.

Thanks
Rahul

I might be mistaken, but since most people seem to use es6 imports with webpack, I'd say that:

// only the css
import { styles } from 'react-select';
// both js and css
import Select, { styles } from 'react-select';

Would be a user-friendly way to import the css.

Not sure if it helps someone, but I used a small wrapper component for react-select which imports the dependencies. The .jsx file wraps the default <Select /> component in a wrapper class which can be created by css modules.

// Select.jsx (ES6)
import React from 'react';
import ReactSelect from 'react-select';
import styles from './Select.scss';

const Select = (props) => {
    return (
        <div className={styles.wrap}><ReactSelect {...props} /></div>
    )
};

Select.propTypes = {};
Select.defaultProps = {};

export default Select;

The .scss file first runs through the sass-loader and then css-loader (with modules). This allows sass variable configuration and helps namespace the default styles to avoid impacting anything else.

// Select.scss (SASS + CSS Modules)
.wrap {
    :global {
        @import "node_modules/react-select/scss/default.scss";
    }
}

Hi,
I am trying to use webpack for bundling my angular1 project. But when I try to use external libraries like bootstrap, angular-bootstrap-calendar etc.. webpack only considers the js ignoring completely the css associated with each library .Now I am forced to import styles from the node-modules which I guess is not the correct way to do it. Is there any proper way to do this?

@bbthorntz I think it is better to mess with webpack config than adding a wrapper component.

Here is my solution to this problem

```javascript
module: {
rules: [
{
test: /(.global.css$|react-select.css)/,
use: [
{
loader: 'style-loader',
},
{
loader: 'css-loader',
},
],
},
{
test: /^((?!.global|react-select).)*.css$/,
use: [
{
loader: 'style-loader',
},
{
loader: 'css-loader',
options: {
modules: true,
importLoaders: 1,
sourceMap: true,
},
},
],
},

@lpan this works too. I'd like to think that the React Component + CSS Modules approach I described stops third-party plugins from adding global styles which might conflict with each other though.

You can do @import "path/to/your/css" inside