isomorphic-style-loader

CSS style loader for Webpack that is optimized for isomorphic (universal) web apps

  • 所有者: kriasoft/isomorphic-style-loader
  • 平台:
  • 许可证: MIT License
  • 分类:
  • 主题:
  • 喜欢:
    0
      比较:

Github星跟踪图

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 #react-starter-kit
chat room on Gitter 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;

License

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


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

主要指标

概览
名称与所有者kriasoft/isomorphic-style-loader
主编程语言JavaScript
编程语言JavaScript (语言数: 1)
平台
许可证MIT License
所有者活动
创建于2015-11-20 10:20:03
推送于2024-12-04 17:09:09
最后一次提交
发布数16
最新版本名称v5.4.0 (发布于 2024-12-04 18:09:07)
第一版名称v0.0.11 (发布于 )
用户参与
星数1.3k
关注者数18
派生数144
提交数106
已启用问题?
问题数133
打开的问题数80
拉请求数49
打开的拉请求数6
关闭的拉请求数25
项目设置
已启用Wiki?
已存档?
是复刻?
已锁定?
是镜像?
是私有?