Giter VIP home page Giter VIP logo

isomorphic-style-loader's Introduction

Isomorphic CSS style loader for Webpack

NPM version NPM downloads Library Size Online Chat

CSS style loader for Webpack that works similarly to style-loader, but is optimized for critical path CSS rendering and also works great in the context of isomorphic apps. It provides two helper methods on to the styles object - ._insertCss() (injects CSS into the DOM) and ._getCss() (returns a CSS string).

See getting started  |  changelog  |  Join #isomorphic-style-loader chat room on Discord to stay up to date

How to Install

$ npm install isomorphic-style-loader --save-dev

Getting Started

Webpack configuration:

module.exports = {
  /* ... */
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [
          'isomorphic-style-loader',
          {
            loader: 'css-loader',
            options: {
              importLoaders: 1
            }
          },
          'postcss-loader'
        ]
      }
    ]
  }
  /* ... */
}

Note: Configuration is the same for both client-side and server-side bundles. For more information visit https://webpack.js.org/configuration/module/.

React component example:

/* App.css */
.root { padding: 10px }
.title { color: red }
/* App.js */
import React from 'react'
import withStyles from 'isomorphic-style-loader/withStyles'
import s from './App.scss'

function App(props, context) {
  return (
    <div className={s.root}>
      <h1 className={s.title}>Hello, world!</h1>
    </div>
  )
}

export default withStyles(s)(App) // <--

P.S.: It works great with CSS Modules! Just decorate your React component with the withStyles higher-order component, and pass a function to your React app via insertCss context variable (see React's context API) that either calls styles._insertCss() on a client or styles._getCss() on the server. See server-side rendering example below:

import express from 'express'
import React from 'react'
import ReactDOM from 'react-dom'
import StyleContext from 'isomorphic-style-loader/StyleContext'
import App from './App.js'

const server = express()
const port = process.env.PORT || 3000

// Server-side rendering of the React app
server.get('*', (req, res, next) => {
  const css = new Set() // CSS for all rendered React components
  const insertCss = (...styles) => styles.forEach(style => css.add(style._getCss()))
  const body = ReactDOM.renderToString(
    <StyleContext.Provider value={{ insertCss }}>
      <App />
    </StyleContext.Provider>
  )
  const html = `<!doctype html>
    <html>
      <head>
        <script src="client.js" defer></script>
        <style>${[...css].join('')}</style>
      </head>
      <body>
        <div id="root">${body}</div>
      </body>
    </html>`
  res.status(200).send(html)
})

server.listen(port, () => {
  console.log(`Node.js app is running at http://localhost:${port}/`)
})

It should generate an HTML output similar to this one:

<html>
  <head>
    <title>My Application</title>
    <script async src="/client.js"></script>
    <style type="text/css">
      .App_root_Hi8 { padding: 10px }
      .App_title_e9Q { color: red }
    </style>
  </head>
  <body>
    <div id="root">
      <div class="App_root_Hi8">
        <h1 class="App_title_e9Q">Hello, World!</h1>
      </div>
    </div>
  </body>
</html>

Regardless of how many styles components there are in the app.js bundle, only critical CSS is going to be rendered on the server inside the <head> section of HTML document. Critical CSS is what actually used on the requested web page, effectively dealing with FOUC issue and improving client-side performance. CSS of the unmounted components will be removed from the DOM.

Then on client-side use hydrate to make your markup interactive:

import React from 'react'
import ReactDOM from 'react-dom'
import StyleContext from 'isomorphic-style-loader/StyleContext'
import App from './App.js'

const insertCss = (...styles) => {
  const removeCss = styles.map(style => style._insertCss())
  return () => removeCss.forEach(dispose => dispose())
}

ReactDOM.hydrate(
  <StyleContext.Provider value={{ insertCss }}>
    <App />
  </StyleContext.Provider>,
  document.getElementById('root')
)

React Hooks Support:

You can also use useStyles inside your React Functional Components, instead of using withStyles. Please note that you still need to pass insertCss function to StyleContext.Provider from top of the tree.

import React from 'react'
import useStyles from 'isomorphic-style-loader/useStyles'
import s from './App.scss'

const App = (props) => {
  useStyles(s);
  return (
    <div className={s.root}>
      <h1 className={s.title}>Hello, world!</h1>
    </div>
  )
};

export default App;

Related Projects

License

The MIT License © 2015-present Kriasoft (@kriasoft). All rights reserved.


Made with ♥ by Konstantin Tarkus (@koistya, blog), Vladimir Kutepov (frenzzy) and contributors

isomorphic-style-loader's People

Contributors

alexanderchr avatar arnoldstoba avatar chinmaychaudhary avatar dazlious avatar dsernst avatar durisvk avatar everettss avatar extg avatar frenzzy avatar geta6 avatar hishayness avatar ifwu avatar inian avatar jasonsanjose avatar jorrit avatar koistya avatar mateo42 avatar mglace avatar nodkz avatar piglovesyou avatar plemarquand avatar rezam7596 avatar rivertam avatar silentimp avatar slopes321 avatar tevcef avatar tinder-rhsiao avatar tstirrat15 avatar vishalvijay avatar yurynix avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

isomorphic-style-loader's Issues

page load animations are executed twice

Does anyone know how to prevent page load animations from executing twice? Example: If I have a button that fades in via pure CSS as soon as the page renders, the animation occurs twice... once when the html and critical CSS load, and again when the CSS bundle is pulled in (currently bundled along with JS). This causes a really weird experience. Is there a simple way to avoid this?

--- Want to back this issue? **[Post a bounty on it!](https://www.bountysource.com/issues/41772771-page-load-animations-are-executed-twice?utm_campaign=plugin&utm_content=tracker%2F26439769&utm_medium=issues&utm_source=github)** We accept bounties via [Bountysource](https://www.bountysource.com/?utm_campaign=plugin&utm_content=tracker%2F26439769&utm_medium=issues&utm_source=github).

withStyles removes all component attributes

When I wrap my components with withStyles, the function essentially creates a fresh class, so all previously defined class attributes, such as static method or component functions are gone. The workaround I have so far is to manually add the attributes.

--- Want to back this issue? **[Post a bounty on it!](https://www.bountysource.com/issues/38374870-withstyles-removes-all-component-attributes?utm_campaign=plugin&utm_content=tracker%2F26439769&utm_medium=issues&utm_source=github)** We accept bounties via [Bountysource](https://www.bountysource.com/?utm_campaign=plugin&utm_content=tracker%2F26439769&utm_medium=issues&utm_source=github).

Multiple withStyles only rendering the first

I asked this on Gitter originally, but I'm struggling to get the following to work (example):

import appStyles from './App.scss`;
import otherStyles from '../OtherComponent/otherStyles.scss';

...

export default withStyles(App, appStyles, otherStyles);

This doesn't throw any errors, and both the styles are within the styles array, only the appStyles are loaded in.

Is this the correct way of going about this?

Access wrapped component functions through ref.

I would like to access a method defined in the child decorated component. I was thinking doing it through ref like suggested there: https://facebook.github.io/react/tips/expose-component-functions.html

I guess I cannot doing that using withStyles decorator because it wrap my component.

Is there an other way ? or should make the wrapped component available when using refs ?

--- Want to back this issue? **[Post a bounty on it!](https://www.bountysource.com/issues/32053146-access-wrapped-component-functions-through-ref?utm_campaign=plugin&utm_content=tracker%2F26439769&utm_medium=issues&utm_source=github)** We accept bounties via [Bountysource](https://www.bountysource.com/?utm_campaign=plugin&utm_content=tracker%2F26439769&utm_medium=issues&utm_source=github).

What's the recommended approach for updating styles when client-side route updates

Ok so let's say that our isomorphic app changes route and the client side router changed the view based on JavaScript. Is there an official approach to retrieving the CSS that was not already inserted in <head>?

In other words:

  1. User navigates to the web site.
  2. Server side renderer returns HTML + CSS with help from isomorphic-style-loader
  3. Server also returns the JS bundle used to render views on the client side (a-la SPA style)
  4. User wants to go to the Account page. Account link is clicked.
  5. Client side router changes view to Account.
  6. The Account page is rendered on the client side and shown

ok, here's my question
7. How should I retrieve the CSS needed for the Account page to show?

One approach could be to use the ExtractTextPlugin, but that doesn't seem to work (because ExtractTextPlugin loader doesn't know how to call _getCss().

Any ideas?

Thanks a bunch

How to use isomorphic-style-loader effectively with component libraries?

I'm trying to use React Toolbox alongside isomorphic-style-loader in my project. React-Toolbox uses CSS modules for its components.

My current solution that I haven't implemented yet is to import each component and its styles, apply withStyles, and export the new component. An example file would look like:

// component_library/Button/index.js
import Button from 'react-toolbox/lib/button';
import buttonStyles from 'react-toolbox/lib/button/theme.scss';
import withStyles from 'isomorphic-style-loader/lib/withStyles';

export default withStyles(buttonStyles)(Button);

Is there a way to apply isomorphic-style-loader's withStyles() across all of a library's components without me having to manually import each file and re-export it?

--- Want to back this issue? **[Post a bounty on it!](https://www.bountysource.com/issues/38158821-how-to-use-isomorphic-style-loader-effectively-with-component-libraries?utm_campaign=plugin&utm_content=tracker%2F26439769&utm_medium=issues&utm_source=github)** We accept bounties via [Bountysource](https://www.bountysource.com/?utm_campaign=plugin&utm_content=tracker%2F26439769&utm_medium=issues&utm_source=github).

Integrating with Extract Text Plugin

Is there a way to integrate the isomorphic style loader with the extract text plugin, which I currently use on prod?
Also, how could you include many styles to single component? (for instance, in my root component, in addition to my style file I also include external styles like font awesome (.less) and bootstrap grid (.scss))

--- Want to back this issue? **[Post a bounty on it!](https://www.bountysource.com/issues/34670738-integrating-with-extract-text-plugin?utm_campaign=plugin&utm_content=tracker%2F26439769&utm_medium=issues&utm_source=github)** We accept bounties via [Bountysource](https://www.bountysource.com/?utm_campaign=plugin&utm_content=tracker%2F26439769&utm_medium=issues&utm_source=github).

Support for critical css without css modules

Not every project uses css modules and there are signs that the react team are against using css modules. Does this library support critical css when components import css like

import component/mystyle.css

Theoretically speaking, it should be possible to find out which components are rendered above the fold, and then resolve css imports from those components into critical path css.

--- Want to back this issue? **[Post a bounty on it!](https://www.bountysource.com/issues/36281242-support-for-critical-css-without-css-modules?utm_campaign=plugin&utm_content=tracker%2F26439769&utm_medium=issues&utm_source=github)** We accept bounties via [Bountysource](https://www.bountysource.com/?utm_campaign=plugin&utm_content=tracker%2F26439769&utm_medium=issues&utm_source=github).

Way to assign two className

Is there any way how from Parent -
<Button className={'row1 column1'} value={'1'}/>
assign these two class to child? I tried -

render() {
     var { value, className, ...other} = this.props;
     return (
         <button className={s[className]}> {value} </button>
     )
}

but it doesnt work. So is there any possibility ?

Want to back this issue? Post a bounty on it! We accept bounties via Bountysource.

Sass function's aren't working

I'm attempting to use the sass function darken() on my links when using :hover however it seems that the function isn't running and just returns the function call:

my sass:

a:hover {
    color: darken($link-color, 30%);
}

the rule is appearing in my inspector like this:

nav a:hover {
    color: darken(#F2CB07, 30%);
}

--- Want to back this issue? **[Post a bounty on it!](https://www.bountysource.com/issues/33001482-sass-function-s-aren-t-working?utm_campaign=plugin&utm_content=tracker%2F26439769&utm_medium=issues&utm_source=github)** We accept bounties via [Bountysource](https://www.bountysource.com/?utm_campaign=plugin&utm_content=tracker%2F26439769&utm_medium=issues&utm_source=github).

Unable to use isomorphic-style-loader without CSS modules

I'm having trouble understanding how this style loader is supposed to work based on the documentation. I don't use CSS modules myself so <div className={s.root}> won't work for me.

Looking down the documentation, I see something like this:

  const css = []; // CSS for all rendered React components
  const context = { insertCss: (styles) => css.push(styles._getCss()) };

To me, this seems like what I want, but I don't know where CSS is getting any styles. I tried this myself and CSS is always [].

My goal is not have Webpack generating pages on load. I have backend.js for the server and bundle.js for the client already working, and I don't wanna use ExtractTextPlugin anymore as it's not choosy about what CSS is loaded; it's a one-time thing.

I'm looking for a method of taking a bunch of site styles (based on what was imported already) and add them to the <head><style>${css}</style></head> server-side on load, then change that back to using style-loader client-side. I thought it'd be nice if I could modify style-loader to do this for me, but it directly writes to the DOM and doesn't have any way of writing to a global string that I can push onto the page myself. isomorphic-style-loader seems to be capable of doing this, but it's unclear how I'm supposed to tell it which styles were loaded so I can generate a style tag.

defaultProps Issues

I seem to be having a problem when I use defaultProps. The props are populated correctly in the object, but the element does not seem to carry them.

For a Parent prop object I have
Object {showShadows: false, fullscreen: true, role: "body", children: Array[2], foreground: Array[0]…} children : Array[2] 0 : Object $$typeof : Symbol(react.element) _owner : ReactCompositeComponentWrapper _self : null _source : null _store : Object key : null props : Object icon : Object key : (...) get key : () ref : (...) get ref : () right : Object __proto__ : Object ref : null type : WithStyles() __proto__ : Object

But, the child props object is:
Object {role: "appbar", style: Object, depth: 0, icon: Object, right: Object…} children : Array[4] depth : 0 draggable : true foreground : Array[0] fullscreen : false getParentSheets : () icon : Object ind : 10 key : (...) get key : () ref : (...) get ref : () right : Object role : "appbar" sheets : Array[0] showShadows : true style : Object __proto__ : Object

The role object is only shown in the child object, but not the parent. If you look under parent->child->type->composedComponent->defaultProps it does show the role object with the default value.

--- Want to back this issue? **[Post a bounty on it!](https://www.bountysource.com/issues/35463977-defaultprops-issues?utm_campaign=plugin&utm_content=tracker%2F26439769&utm_medium=issues&utm_source=github)** We accept bounties via [Bountysource](https://www.bountysource.com/?utm_campaign=plugin&utm_content=tracker%2F26439769&utm_medium=issues&utm_source=github).

Changing class name doesn't hot-reload new class name and apply it to JS

Want to back this issue? Post a bounty on it! We accept bounties via Bountysource.

--- Want to back this issue? **[Post a bounty on it!](https://www.bountysource.com/issues/38681115-changing-class-name-doesn-t-hot-reload-new-class-name-and-apply-it-to-js?utm_campaign=plugin&utm_content=tracker%2F26439769&utm_medium=issues&utm_source=github)** We accept bounties via [Bountysource](https://www.bountysource.com/?utm_campaign=plugin&utm_content=tracker%2F26439769&utm_medium=issues&utm_source=github).

documentation is incomplete

the usage example in the doc needs some love, I had a better understanding of how to use it by looking at:

https://github.com/kriasoft/react-starter-kit/blob/master/src/client.js
and
https://github.com/kriasoft/react-starter-kit/blob/master/src/server.js

the doc needs to give an good example on how style is collected and inserted.

--- Want to back this issue? **[Post a bounty on it!](https://www.bountysource.com/issues/29894776-documentation-is-incomplete?utm_campaign=plugin&utm_content=tracker%2F26439769&utm_medium=issues&utm_source=github)** We accept bounties via [Bountysource](https://www.bountysource.com/?utm_campaign=plugin&utm_content=tracker%2F26439769&utm_medium=issues&utm_source=github).

extract-text-webpack-plugin

hi,can use extract-text-webpack-plugin when release?

--- Want to back this issue? **[Post a bounty on it!](https://www.bountysource.com/issues/30761410-extract-text-webpack-plugin?utm_campaign=plugin&utm_content=tracker%2F26439769&utm_medium=issues&utm_source=github)** We accept bounties via [Bountysource](https://www.bountysource.com/?utm_campaign=plugin&utm_content=tracker%2F26439769&utm_medium=issues&utm_source=github).

babel-node syntax error

When running in development babel-cli (babel-node) is throwing syntax error on CSS imports when I run my server.js. Any suggestion on how to solve this?

`products.scss: Unexpected token (1:0)

1 | .products {
| ^
2 | padding-top: 24px;
3 | padding-bottom: 24px;`

I've seen the suggestion to wrap css in conditional requires based on ENV, but that doesn't seem to fit in with server side rendering concept that this plugin is solving.

Add comments for `const id = `${moduleId}-${i}`;`

explaining why is it done so and why not simply use moduleId

--- Want to back this issue? **[Post a bounty on it!](https://www.bountysource.com/issues/40839067-add-comments-for-const-id-moduleid-i?utm_campaign=plugin&utm_content=tracker%2F26439769&utm_medium=issues&utm_source=github)** We accept bounties via [Bountysource](https://www.bountysource.com/?utm_campaign=plugin&utm_content=tracker%2F26439769&utm_medium=issues&utm_source=github).

_getCss() method should return module ID in addition to CSS string

This would allow to render multiple <style> elements on the server for each UI module and being able to reuse them on a client during the initial page load.

Ref #13

--- Want to back this issue? **[Post a bounty on it!](https://www.bountysource.com/issues/30934003-_getcss-method-should-return-module-id-in-addition-to-css-string?utm_campaign=plugin&utm_content=tracker%2F26439769&utm_medium=issues&utm_source=github)** We accept bounties via [Bountysource](https://www.bountysource.com/?utm_campaign=plugin&utm_content=tracker%2F26439769&utm_medium=issues&utm_source=github).

Hot reloaded styles not persisting on route change

Hello

We've got this module in our application, setup as per the README. We also have hot module reloading enabled. When changing styles (SCSS), the page hot reloads and the styles are updated. However if we navigate to a different page (client side using React Router) and then back to the original page the styles have reverted back.

When we navigate back, the console shows:
image

This should be blue (what it changes to after hot reloading). However when we navigate into the file, the color is actually correct:
image

Another thing we noticed, was that this is only happening on components which are rendered on page load. Hot reloading of styles persists if we navigate to a page which the client loads. It has nothing to do with the initial styles injected by the client as we removed this and the same issue persisted.

Our project is here: https://github.com/teamfa/sails-universal-react-starter

We've removed loads of Webpack options/config but the issue still exists. Any idea what this could be?

Breaks TransitionGroup

When wrapping a component with "withStyles" that is inside a 'react-addons-transition-group' the animation lifecycle events such as componentWillEnter and componentWillLeave do not get triggered. Is there a way around this or am I doing something wrong?

--- Want to back this issue? **[Post a bounty on it!](https://www.bountysource.com/issues/39845422-breaks-transitiongroup?utm_campaign=plugin&utm_content=tracker%2F26439769&utm_medium=issues&utm_source=github)** We accept bounties via [Bountysource](https://www.bountysource.com/?utm_campaign=plugin&utm_content=tracker%2F26439769&utm_medium=issues&utm_source=github).

Unexpected token

I keep getting this error and I am not sure if the component is failing or I am configuring it incorrectly. My Webpack config is exactly to the documentation, I am also using postcss-loader:

Unexpected token (2:0)
  1 |
> 2 | :root {
    | ^
  3 |     --panel-width :30vw;
  4 |     --panel-color : #4E4C67;
  5 | }

my component :

import withStyles from 'isomorphic-style-loader/lib/withStyles';
import s from './groupsView.css';

class MyComponent extends Component {
    render() {
        return(
            <div className='groups'>
              <h2>Groups</h2>
            </div>
        )
    }
}
export default withStyles(s)(MyComponent);

and my css loaders:

const cssLoader = {
    test: /\.css$/,
    exclude: /(node_modules|bower_components)/,
    loaders: [ 'isomorphic-style-loader', 'css-loader?modules&localIdentName=[name]_[local]_[hash:base64:3]', 'postcss-loader' ]
} 

Any help is much appreciated.
Thanks

--- Want to back this issue? **[Post a bounty on it!](https://www.bountysource.com/issues/37777818-unexpected-token?utm_campaign=plugin&utm_content=tracker%2F26439769&utm_medium=issues&utm_source=github)** We accept bounties via [Bountysource](https://www.bountysource.com/?utm_campaign=plugin&utm_content=tracker%2F26439769&utm_medium=issues&utm_source=github).

keyframes in :global don't work

I included some CSS animation keyframes under :global at the root of my app. The keyframe names don't render in the global scope, and they are wrapped in curly brackets. When the keyframes are used in other global classes, they do not take on the scoped name.

An example:

/* Layout.css */
:global {
   .slide-enter {
      animation: slide-in 0.5s forwards;
      -webkit-animation: slide-in 0.5s forwards;
   }
   @keyframes slide-in {
      100% { transform: translateX(0%); }
   }
}

gets included as:

{
  @keyframes Layout-slide-in-2RRX8 {
    100% { -webkit-transform: translateX(0%); transform: translateX(0%); }
  }
}
.slide-enter {
  animation: slide-in 0.5s forwards;
  -webkit-animation: slide-in 0.5s forwards;
}

Thoughts?

insertCss doesn't insert second style in a set.

A less file results in an array with two styles. When this array is passed to insertStyles it skips over the second style because they both have the same id.

I confirmed that the output of import ps from '!css!less!../file.less'; also contains duplicate IDs, so it seems that checking a blacklist of ids (inserted) won't ever have the desired effect.

insertcss

--- Want to back this issue? **[Post a bounty on it!](https://www.bountysource.com/issues/30520500-insertcss-doesn-t-insert-second-style-in-a-set?utm_campaign=plugin&utm_content=tracker%2F26439769&utm_medium=issues&utm_source=github)** We accept bounties via [Bountysource](https://www.bountysource.com/?utm_campaign=plugin&utm_content=tracker%2F26439769&utm_medium=issues&utm_source=github).

How to include external styles without prefixing?

Lets say I want to use Flexbox Grid in my application. I have a root App component, which is the main component everything is rendered inside.

The flexboxgrid css contains classes which I'd like to use throughout other components. However, they get prefixed with the App component name and hash. There's a couple of workarounds, but none seem good/clean enough.

1 - By directly including it in the document

This would mean doing it the vanilla way in the document <head>. However we can't bundle/control it with webpack and it's an additional HTTP call.

2 - Use require & a CSS only loader with ExtractTextPlugin

Now in our App component we can use require('flexboxgrid');. However this assumes that all .css files are external global modules.


Work around 2 is the cleanest, however I just feel there should be a way to include styles with the isomorphic style loader without prefixing. Normalize.css will work fine, since it doesn't have any CSS classes, but importing a global CSS file with classes is a faff.

Where is `context` set?

I'm trying to add this to server-side render a particular component with its style.

I've installed this package and prepended it to the list of loaders for .scss:

  module: {
    loaders: [
      JS_LOADER,
      ...config.module.loaders,
      {
        test: /\.scss$/,
-        loaders: ['css-loader', 'postcss-loader'],
+        loaders: ['isomorphic-style-loader', 'css-loader', 'postcss-loader'],
      },
    ],
  },

I've added all the code described in the readme for stateless react components:

import React, { PropTypes } from 'react'
import style from './About.scss'

function About(props, context) {
  console.log('context:', context)
  context.insertCss(style)
  return (
    <div className="About">
      ...
    </div>
  )
}

About.contextTypes = { insertCss: PropTypes.func.isRequired }

export default About

But when I try to build this on the server (using npm start from react-static-boilerplate) these errors are thrown:

Warning: Failed Context Types: Required context `insertCss` was not specified in `About`. Check the render method of `_default`.
context: { insertCss: undefined }
TypeError: context.insertCss is not a function
    at new About (/Users/dsernst/Documents/project/build/app.node.js:1401:13)

Any idea why context.insertCss is undefined? Is there a step I'm missing? Was I supposed to invoke getChildContext somewhere up the tree?

css duplicates

By using this module, one piece of CSS code exists both in HTML and in JavaScript. Besides, all require mentioned CSS stays in JavaScript. The module itself create duplicates (and make HTML much bigger).

--- Want to back this issue? **[Post a bounty on it!](https://www.bountysource.com/issues/30855681-css-duplicates?utm_campaign=plugin&utm_content=tracker%2F26439769&utm_medium=issues&utm_source=github)** We accept bounties via [Bountysource](https://www.bountysource.com/?utm_campaign=plugin&utm_content=tracker%2F26439769&utm_medium=issues&utm_source=github).

Any way to import CSS without appending component name to front of classes?

I want to use a component made by someone else in my project:

https://github.com/facebook/fixed-data-table

But I can't figure out how to import the CSS for this component without appending the component name to all the CSS classes. Is there any way to do that?

--- Want to back this issue? **[Post a bounty on it!](https://www.bountysource.com/issues/31249953-any-way-to-import-css-without-appending-component-name-to-front-of-classes?utm_campaign=plugin&utm_content=tracker%2F26439769&utm_medium=issues&utm_source=github)** We accept bounties via [Bountysource](https://www.bountysource.com/?utm_campaign=plugin&utm_content=tracker%2F26439769&utm_medium=issues&utm_source=github).

Using with react-router

Hello, how to provide context to react-router?

--- Want to back this issue? **[Post a bounty on it!](https://www.bountysource.com/issues/30635943-using-with-react-router?utm_campaign=plugin&utm_content=tracker%2F26439769&utm_medium=issues&utm_source=github)** We accept bounties via [Bountysource](https://www.bountysource.com/?utm_campaign=plugin&utm_content=tracker%2F26439769&utm_medium=issues&utm_source=github).

How to make hot reloading work?

In my case it doesn't work at all. JSX in component itself is hot reloaded on change, but styles in withStyles() are not.

--- Want to back this issue? **[Post a bounty on it!](https://www.bountysource.com/issues/39174804-how-to-make-hot-reloading-work?utm_campaign=plugin&utm_content=tracker%2F26439769&utm_medium=issues&utm_source=github)** We accept bounties via [Bountysource](https://www.bountysource.com/?utm_campaign=plugin&utm_content=tracker%2F26439769&utm_medium=issues&utm_source=github).

`insertCss` constraint

Aloha everyone,

during test coverage of my component i found the problem with shallow rendering.
For example code using enzyme:

const StyledComponent = withStyles('')(
  class Foo extends Component {
    render() {
      return <div />;
    }
  }
);

expect(shallow(<StyledComponent />).html()).to.equal('<div></div>');

After execute this code, test return error: Cannot read property 'apply' of undefined.
I found the cause of this error, and change withStyles module for fix error while maintaining backward compatibility.

About reason of error. I think this insertCss as required property in propTypes is unjustified constraint, because when you need create isolated test of component you can't do this.

What you think about this issue?

Thanks!

P.S. if maintainer or community decide that actually problem, i can do PR for resolve this issue.

--- Want to back this issue? **[Post a bounty on it!](https://www.bountysource.com/issues/38033508-insertcss-constraint?utm_campaign=plugin&utm_content=tracker%2F26439769&utm_medium=issues&utm_source=github)** We accept bounties via [Bountysource](https://www.bountysource.com/?utm_campaign=plugin&utm_content=tracker%2F26439769&utm_medium=issues&utm_source=github).

Overriding library CSS classes

Hi there,

Is there a way to process a CSS file with withStyles and leave some of the classes' names as-is?

.myClass.container {
   /* some CSS */
}
render() {
    return (
       <div className={s.myClass}>
           <Container></Container>
       </div>
    );
}

Assuming the above <Container component will render with class="container", for example if it were a Bootstrap container, then I would like some way for my CSS above to be able to select it. But when the CSS gets loaded by Webpack, it gets an ID, viz.:

.myClass_3eF.container_1l6 {
  /* my CSS */
}

Which causes container_1I6 for example never to reference the required class. I would like some way to ensure myClass does get its ID, and container retains its name. Is this possible?

fails to render '@import ~xyz'

it seems not be able to resolve the following statement from .scss, any ideas?

@import `~flexboxgrid`

flexboxgrid is a css file resides in the node_modules/ , and the error message I got:

Failed to find '~flexboxgrid' from /Users/roylee/dev/js/MyApp

--- Want to back this issue? **[Post a bounty on it!](https://www.bountysource.com/issues/30288996-fails-to-render-import-xyz?utm_campaign=plugin&utm_content=tracker%2F26439769&utm_medium=issues&utm_source=github)** We accept bounties via [Bountysource](https://www.bountysource.com/?utm_campaign=plugin&utm_content=tracker%2F26439769&utm_medium=issues&utm_source=github).

How to pass styles to a component?

Suppose, I have a component Table which gets instantiated by the Component Reports. I would like to pass styles to the Table component (constructor?) for it to use them when generating a table.

--- Want to back this issue? **[Post a bounty on it!](https://www.bountysource.com/issues/34698619-how-to-pass-styles-to-a-component?utm_campaign=plugin&utm_content=tracker%2F26439769&utm_medium=issues&utm_source=github)** We accept bounties via [Bountysource](https://www.bountysource.com/?utm_campaign=plugin&utm_content=tracker%2F26439769&utm_medium=issues&utm_source=github).

Replace React.Component with React.PureComponent inside withStyles.js

This will ensure that stateless functional component decorated with withStyles(..) won't re-render unless they receive new props.


Want to back this issue? Post a bounty on it! We accept bounties via Bountysource.

--- Want to back this issue? **[Post a bounty on it!](https://www.bountysource.com/issues/39126082-replace-react-component-with-react-purecomponent-inside-withstyles-js?utm_campaign=plugin&utm_content=tracker%2F26439769&utm_medium=issues&utm_source=github)** We accept bounties via [Bountysource](https://www.bountysource.com/?utm_campaign=plugin&utm_content=tracker%2F26439769&utm_medium=issues&utm_source=github).

How to remove unused CSS Loader mappings?

I want to reduce the bloat caused by css loader className mapping when used with SASS @import statement.

Let me explain with an example:

_common.scss

    .smallSpacing {
        margin: 0 10px;
    }

    .largeSpacing {
        margin: 0 20px;
    }

App.scss

    @import 'common';

    .app {
        @extend .largeSpacing;  
    }

App.js

    import styles from './App.scss';

    export default const App = () => <div className={styles.app}>Hello!</div>; 

As expected, I created the App component and used .app CSS class to style it. Styles are extended from _common.scss. This works fine, but there's an unneeded code bloat.

Because I imported _common.scss, the bundle will include mappings for .smallSpacing and .largeSpacing, even though .smallSpacing was never really used in the component.

This is not a big deal for small apps, but with huge apps that have large sets of common styles, the mappings significantly increase application size.

Is there a way to reduce this overhead?

I'm not sure if I should be asking here or in the CSS-Loader repo. I appreciate your help.

--- Want to back this issue? **[Post a bounty on it!](https://www.bountysource.com/issues/37387771-how-to-remove-unused-css-loader-mappings?utm_campaign=plugin&utm_content=tracker%2F26439769&utm_medium=issues&utm_source=github)** We accept bounties via [Bountysource](https://www.bountysource.com/?utm_campaign=plugin&utm_content=tracker%2F26439769&utm_medium=issues&utm_source=github).

How to write proper handler in insertCss on client side for multiple arguments in withStyles?

Suggested in #37 by @frenzzy handling for multiple arguments in withStyles function
withStyles(s1, s2)(Component)
on the client side was:

const onInsertCssHandler = (...styles) => {
    styles.forEach(style => style._insertCss());
};

ReactDOM.render(
    <WithStylesContext onInsertCss={onInsertCssHandler}>
        // irrelevant 
    </WithStylesContext>,
    document.getElementById('root')
);

WithStylesContext - just for documentation:

import { Component, PropTypes, Children } from 'react';

class WithStylesContext extends Component {
    static propTypes = {
        children: PropTypes.element.isRequired,
        onInsertCss: PropTypes.func.isRequired,
    };

    static childContextTypes = {
        insertCss: PropTypes.func.isRequired,
    };

    getChildContext() {
        return { insertCss: this.props.onInsertCss };
    }

    render() {
        return Children.only(this.props.children);
    }
}

export default WithStylesContext;

This solution indeed append multiple styles properly, but has problem with removing them when they are no longer referenced by UI components.

I think the issue is related with not returning function in onInsertCssHandler. For reference: original handler in react-starter-kit.

How to write this handler and still have removing not used styles functionality?

_insertCss method produces duplications

Hi,
I have a problem with Isomorphic-style-loader because it injects the same css module multiple times.
When I call _instertCSs in the following scenario:
_insertCSS([id1,style1], [id2, style2])
_insertCss([id2, style2], [id1, style1])

I would expect heaving only 2 scripts tags in HEAD section after rendering. In my situation I end up heaving 4 <script> sections.

_insertCss method uses index of the script to construct internal id and uses it to check if the script has been already injected.
in my situation inserted dictionary looks following:
{
"id1-0":1,
"id2-0":1,
"id1-1":1,
"id2-1":1
}

Should you use only moduleId as a key in the dictionary?

--- Want to back this issue? **[Post a bounty on it!](https://www.bountysource.com/issues/39474795-_insertcss-method-produces-duplications?utm_campaign=plugin&utm_content=tracker%2F26439769&utm_medium=issues&utm_source=github)** We accept bounties via [Bountysource](https://www.bountysource.com/?utm_campaign=plugin&utm_content=tracker%2F26439769&utm_medium=issues&utm_source=github).

Integration with webpack-isomorphic-tools

I'd like to share my experience using isomorphic-style-loader in a project that uses webpack-isomorphic-tools to convert modules to JS on the server-side, not webpack loaders.

Here are my notes: catamphetamine/webpack-isomorphic-tools#59 (comment)

--- Want to back this issue? **[Post a bounty on it!](https://www.bountysource.com/issues/32313144-integration-with-webpack-isomorphic-tools?utm_campaign=plugin&utm_content=tracker%2F26439769&utm_medium=issues&utm_source=github)** We accept bounties via [Bountysource](https://www.bountysource.com/?utm_campaign=plugin&utm_content=tracker%2F26439769&utm_medium=issues&utm_source=github).

No hot reload on first use

Say I create a new component in my project which is currently being run using webpack dev server. I create a matching .css file for it and load it using withStyles, the style in this file is not hot reloaded.
Let me clarify in saying that after refreshing the page, the style does get loaded, and also any future changes in the css file also cause hot reload, which is great obviously.
So the only problem is when I initially trying to load a new style file.

Minor problem IMO, but still wanted to let you know, awesome package!

--- Want to back this issue? **[Post a bounty on it!](https://www.bountysource.com/issues/35285751-no-hot-reload-on-first-use?utm_campaign=plugin&utm_content=tracker%2F26439769&utm_medium=issues&utm_source=github)** We accept bounties via [Bountysource](https://www.bountysource.com/?utm_campaign=plugin&utm_content=tracker%2F26439769&utm_medium=issues&utm_source=github).

Error "Cannot resolve module" and "Unexpected token ."

I'm using React-Starter-Kit and trying to integrate with AdminLTE. When I imported a css from AdminLTE I got this error.

If I change the background url from url(blue.png) to url("./blue.png"), the error "Cannot resolve module" will disappear but the error "Unexpected token ." still exist.

webpack built 706e73eda3d2e1bd0af7 in 6548ms
Child
    Time: 6548ms

    ERROR in ./~/css-loader?{"sourceMap":true,"modules":true,"localIdentName":"[name]_[local]_[hash:base64:3]","minimize":false}!./~/postcss-loader?pack=default!./~/admin-lte/plugins/iCheck/square/blue.css
    Module not found: Error: Cannot resolve module 'blue.png' in /home/nginx/domains/vps.manhhailua.com/public/node_modules/admin-lte/plugins/iCheck/square
     @ ./~/css-loader?{"sourceMap":true,"modules":true,"localIdentName":"[name]_[local]_[hash:base64:3]","minimize":false}!./~/postcss-loader?pack=default!./~/admin-lte/plugins/iCheck/square/blue.css 6:342-361

    ERROR in ./~/css-loader?{"sourceMap":true,"modules":true,"localIdentName":"[name]_[local]_[hash:base64:3]","minimize":false}!./~/postcss-loader?pack=default!./~/admin-lte/plugins/iCheck/square/blue.css
    Module not found: Error: Cannot resolve module '[email protected]' in /home/nginx/domains/vps.manhhailua.com/public/node_modules/admin-lte/plugins/iCheck/square
     @ ./~/css-loader?{"sourceMap":true,"modules":true,"localIdentName":"[name]_[local]_[hash:base64:3]","minimize":false}!./~/postcss-loader?pack=default!./~/admin-lte/plugins/iCheck/square/blue.css 6:1768-1790
Child
    Time: 5675ms
            Asset    Size  Chunks             Chunk Names
        server.js  190 kB       0  [emitted]  main
    server.js.map  184 kB       0  [emitted]  main
webpack: bundle is now VALID.
/home/nginx/domains/vps.manhhailua.com/public/node_modules/admin-lte/plugins/iCheck/square/blue.css:3
.icheckbox_square-blue,
^
SyntaxError: Unexpected token .
    at Object.exports.runInThisContext (vm.js:76:16)
    at Module._compile (module.js:513:28)
    at Object.Module._extensions..js (module.js:550:10)
    at Module.load (module.js:458:32)
    at tryModuleLoad (module.js:417:12)
    at Function.Module._load (module.js:409:3)
    at Module.require (module.js:468:17)
    at require (internal/module.js:20:19)
    at Object.module.exports.Object.defineProperty.value (/home/nginx/domains/vps.manhhailua.com/public/build/webpack:/external "admin-lte/plugins/iCheck/square/blue.css":1:1)
    at __webpack_require__ (/home/nginx/domains/vps.manhhailua.com/public/build/webpack:/webpack/bootstrap f9baa6a0523f95e79945:19:1)
    at Object.<anonymous> (/home/nginx/domains/vps.manhhailua.com/public/build/webpack:/routes/login/Login.js:16:1)
    at __webpack_require__ (/home/nginx/domains/vps.manhhailua.com/public/build/webpack:/webpack/bootstrap f9baa6a0523f95e79945:19:1)
    at Object.module.exports.Object.defineProperty.value (/home/nginx/domains/vps.manhhailua.com/public/build/webpack:/routes/login/index.js:11:1)
    at __webpack_require__ (/home/nginx/domains/vps.manhhailua.com/public/build/webpack:/webpack/bootstrap f9baa6a0523f95e79945:19:1)
    at Object.module.exports.Object.defineProperty.value (/home/nginx/domains/vps.manhhailua.com/public/build/webpack:/routes/index.js:16:1)
    at __webpack_require__ (/home/nginx/domains/vps.manhhailua.com/public/build/webpack:/webpack/bootstrap f9baa6a0523f95e79945:19:1)
/home/nginx/domains/vps.manhhailua.com/public/tools/runServer.js:71
        throw new Error(`Server terminated unexpectedly with code: ${ code } signal: ${ signal }`);
        ^

Error: Server terminated unexpectedly with code: 1 signal: null
    at ChildProcess.server.once (/home/nginx/domains/vps.manhhailua.com/public/tools/runServer.js:53:15)
    at ChildProcess.g (events.js:286:16)
    at emitTwo (events.js:106:13)
    at ChildProcess.emit (events.js:191:7)
    at Process.ChildProcess._handle.onexit (internal/child_process.js:204:12)

Use just client side?

I just came across this project today and I'm not quite sure if this is something that can be used JUST client side (static-only site) to grab the critical path css?

How to reference a class from another stylesheet without renaming it?

I want to do something like:

.my_app_header_class { .some-component-i-dont-manage { color: #ccc } }

But I would like to indicate for the .some-component-i-dont-manage to not get renamed since it needs to match the class in the npm package.

Adding className to the component I'm using is one way, however this doesn't work when that component has nested elements it creates that I need to reference.

What is the proper way to do this?

ignore some styles

Hi,

i using also react-bootstrap, and i want to override some styles of bootstrap... but i can't (i can but not for all elements)

is there some flag for ignore? or how i can tell to don't rename this style?

Override isomorphic-style-loader in the request behave different on client and backed

Problem

Webpack setup from react-starter-kit create different output on client and backend build when use custom loaders in request #36.

Setup

component with styles - I want to disable modules in css-loader since is external library

import s from '!isomorphic-style!css-loader?modules=false!react-select/dist/react-select.css';
const Select = withStyles(s)(require('react-select'));

// ...
 <Select />
// ...

loader in weback - common setup for client and backend (from react-starter-kit)

{
  test: /\.css/,
  loaders: [
    'isomorphic-style-loader',
    `css-loader?${JSON.stringify({
      sourceMap: DEBUG,
      // CSS Modules https://github.com/css-modules/css-modules
      modules: true,
      localIdentName: DEBUG ? '[name]_[local]_[hash:base64:3]' : '[hash:base64:4]',
      // CSS Nano http://cssnano.co/options/
      minimize: !DEBUG,
    })}`,
    'postcss-loader?pack=default',
  ],
},

Output

When I use DEBUG = false:

client side is minimize

.Select{position:relative}.Select,.Select div,.Select input,.Select span{box-sizing:border-box}.Select.is-disabled>.Select-control{background-color:#f9f9f9}

backend side is not minimize

/**
 * React Select
 * ============
 * Created by Jed Watson and Joss Mackison for KeystoneJS, http://www.keystonejs.com/
 * https://twitter.com/jedwatson https://twitter.com/jossmackison https://twitter.com/keystonejs
 * MIT License: https://github.com/keystonejs/react-select
*/
.Select {
  position: relative;
}
.Select,
.Select div,
.Select input,
.Select span {
  -webkit-box-sizing: border-box;
  -moz-box-sizing: border-box;
  box-sizing: border-box;
}

Tips

It looks that when backend is generated it wipes out all settings from loader in webpack - since minimize is by default false. But why is not doing the same on the client side?

--- Want to back this issue? **[Post a bounty on it!](https://www.bountysource.com/issues/35163699-override-isomorphic-style-loader-in-the-request-behave-different-on-client-and-backed?utm_campaign=plugin&utm_content=tracker%2F26439769&utm_medium=issues&utm_source=github)** We accept bounties via [Bountysource](https://www.bountysource.com/?utm_campaign=plugin&utm_content=tracker%2F26439769&utm_medium=issues&utm_source=github).

[request] Example without usage of a boilerplate kit, css-modules or withStyles

I've been going through the code and tried to source help on the Discord Reactiflux website to see if I could take the example usage provided and make it work with my own server setup :
https://github.com/JaxCavalera/Tagged_Isomorphic/blob/master/src/server.jsx

The most challenging lines to follow are specifically related to :

const context = { insertCss: (styles) => css.push(styles._getCss()) };

I don't really understand the purpose of using that variable and I'm unsure of where the styles variable is being defined or how it ends up being an object with functions such as _getCss().

Will isomorphic-style-loader work without the use of the withStyles Higher order function or is that a dependency module that needs to manually be imported and used in each of my components.. which would seem to then signify that I need to also use css-modules so that makes 2 dependencies.

I'm not very clear on css-modules and what benefit it brings to the table.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.