nwb generates Webpack module.rules
configuration which allows you to import stylesheets directly from JavaScript modules:
import './App.css'
import React from 'react'
export default class App extends React.Component {
// ...
}
When running a development server, imported stylesheets will be injected into the page using <style>
elements and hot-reloaded when they change.
When running a production build, imported stylesheets will be extracted out to static .css
files.
Note: each generated Webpack rule and chained loader has an associated unique id which can be used in
webpack.rules
configuration to tweak its configuration.
Without any webpack.styles
configuration, nwb generates a rule (id: css-rule
) which handles .css
files by chaining together a number of loaders:
-
loader id:
style
- applies styles using style-loaderNote: use of this loader is only configured when running a development server
-
loader id:
css
- handles URLs, minification and can be configured to enable CSS Modules, using css-loaderDefault config:
{options: {importLoaders: 1}}
-
loader id:
postcss
- processes CSS with PostCSS plugins using postcss-loader; by default, this is configured to manage vendor prefixes in CSS using AutoprefixerDefault config:
{options: {plugins: [Autoprefixer]}}
To allow you to import preprocessed stylesheets just by having a CSS preprocessor plugin installed, nwb will generate a default Webpack rule for every CSS preprocessor plugin in your package.json
.
For example, if you install the nwb-sass plugin, nwb will also generate a default sass-rule
rule which will allow you to import .scss
and .sass
stylesheets, chaining together the same loaders as the default css-rule
above plus a loader for the preprocessor.
Ids for configuring this rule and its loaders using webpack.rules
follow a similar pattern css-rule
, except they prefix the name of the preprocessor to make them unique:
- rule id:
sass-rule
- loader id:
sass-style
- loader id:
sass-css
- loader id:
sass-postcss
- loader id:
sass
- preprocesses imported stylesheets using sass-loader
- loader id:
The same pattern applies for nwb-stylus and nwb-less.
e.g. to enable CSS Modules in the default sass-rule
's css-loader
:
module.exports = {
webpack: {
rules: {
'sass-css': {
modules: true,
localIdentName: '[name]__[local]__[hash:base64:5]'
}
}
}
}
By default, nwb uses PostCSS to manage vendor prefixes in CSS using Autoprefixer.
If you want to make more significant use of PostCSS, you can use webpack.rules
to provide your own list of plugins.
e.g. to provide your own list of plugins for your app's own CSS, configure webpack.rules.postcss
:
module.exports = {
webpack: {
rules: {
postcss: {
plugins: [
require('precss')()
require('autoprefixer')()
]
}
}
}
}
If your application needs more than one stylesheet rule, you can configure generation of multiple rules using webpack.styles
config.
This should be an object defining lists of style rule configuration objects, with properties named for the type of rule being configured.
Rules for vanilla .css
files are configured with a css
property and rules for CSS preprocessor plugins are configured using the appropriate plugin name, e.g. sass
when using nwb-sass
.
module.exports = {
webpack: {
styles: {
css: [/* ... */],
sass: [/* ... */]
}
}
}
Stylesheet rule configuration objects trigger generation of a rule with chained loaders as per the default configuration above and allow you to configure loader options for the rule.
Specify which files the rule applies to using test
, include
and exclude
properties.
Default test
config will be provided for each style type - e.g. /\.css$/
for css
rules - but you can override it if necessary.
Loader options can be configured using a property which matches the loader's name: style
, css
,postcss
or the name of any preprocessor loader being used.
e.g. to configure use of CSS modules within a specific directory:
// Create a rule which uses CSS Modules for CSS imported from src/components
{
include: path.resolve('src/components')
// The 'css' property within a stylesheet rule configures options for css-loader
css: {
modules: true,
localIdentName: (
process.env.NODE_ENV === 'production'
? '[path][name]-[local]-[hash:base64:5]'
: '[hash:base64:5]'
)
}
}
With this rule alone, CSS imported from other directories, including node_modules/
, won't be handled, so we should specify another rule to handle everything else:
// Create a catch-all rule for all other CSS stylesheets
{
exclude: path.resolve('src/components')
}
Putting these together, the final style rule config would look like this:
module.exports = {
webpack: {
// Custom stylesheet rule configuration
styles: {
// The 'css' property is used to configure rules for vanilla CSS files
css: [
// Create a rule which uses CSS modules for CSS imported from src/components
{
include: path.resolve('src/components')
// Configuration options for css-loader
css: {
modules: true,
localIdentName: (
process.env.NODE_ENV === 'production'
? '[path][name]-[local]-[hash:base64:5]'
: '[hash:base64:5]'
)
}
},
// Create a catch-all rule for all other CSS stylesheets
{
exclude: path.resolve('src/components')
}
]
}
}
}
Using this configuration, it's possible to specify multiple rules for stylesheets imported by your app and your dependencies.
For example, React Toolbox is a dependency which imports stylesheets on your behalf and requires a specific Webpack setup using CSS Modules and PostCSS-cssnext.
var reactToolboxVariables = {
'button-height': '30px'
}
module.exports = {
webpack: {
styles: {
css: [
// Create a rule which provides the setup [email protected] needs
{
include: /react-toolbox/,
css: {
modules: true,
localIdentName: "[name]--[local]--[hash:base64:8]",
sourceMap: true
},
// The 'postcss' property within a style rule configures options for
// postcss-loader.
postcss: {
plugins: [
require('postcss-cssnext')({
features: {
customProperties: {
variables: reactToolboxVariables
}
}
}),
require('postcss-modules-values'),
]
}
},
// Create a catch-all rule for other, regular CSS
{
exclude: /react-toolbox/
}
]
}
}
}
If you want to handle creating style rules manually, you can disable nwb's default rules by configuring webpack.styles
as false
:
module.exports = {
webpack: {
styles: false
}
}
If you need to use any of the Webpack loaders nwb manages dependencies for - e.g. css-loader
and postcss-loader
- refer to them by loader name in your webpack.extra
config or webpack.config
function. nwb configures Webpack to resolve these loaders correctly if they're not installed locally in your project.