it's different than the other rework webpack loader because it treats each css file as a different webpack module.
if you're not familiar with how webpack loaders work, you should checkout the main documentation first. webpack loaders allow you to transform the source of webpack modules.
rework allows you to create modular css transformations.
$ npm install --save-dev rework-webpack-loader
you can apply
rework-webpack-loader to your css either explicitly in the
or you can apply it to all css files via a configuration file:
var reworkLoader = ;var reworkCalc = ;moduleexports =module:loaders:test: /\.css$/ loader: 'style-loader!rework-webpack-loader'// ...// the rest of the config...rework:usereworkCalc// ... other rework plugins ...;
rework-webpack-loader has to do some tricky things to get
and variables working correctly. so a full featured config might look like
var reworkLoader = ;var reworkVars = ;var reworkCalc = ;var reworkCustomMedia = ;// if you want to have something like a theme file that can override the css// variables defined directly in the css file, make a variable map.var varMap = reworkLoader;moduleexports =resolve:// if you want to @import stuff you installed with npm, such as suit css,// you probably need to include `style` in your `packageMains` configpackageMains:'webpack''browser''web''browserify''jam' 'main''style''main'// ...module:loaders:test: /\.css$/ loader: 'style-loader!rework-webpack-loader'// ...// ...rework:use:reworkLoaderpluginsimportsreworkLoaderpluginsurlsreworkLoaderpluginsreworkCalc;
the plugin api is the same as rework's, with a couple additions:
rework-webpack-loaderwill wait for it to complete before applying the next plugin.
rework-webpack-loaderworks similarly to the default
css-loader plugin wasn't enough for my needs because i wanted
features like css variables and the
the issue with the existing
rework-loader is it doesn't treat each css file
as a separate webpack module, so you lose all of webpack's dependency tracking
(a.k.a. the big motivator for using a module system in the first place).
consider an app with 3 css files:
base.css: css reset and utility classes
menu.css: styles for a re-usable css drop-down menu, which
base.csssince it builds on those utility classes
app.css: styles specific to this application, which also
base.csssince the app needs the utility classes and reset
app.js: the rest of your app code, which presumably uses the menu component
your dependency tree looks something like this:
css preprocessors that don't treat each css file as a separate module will end
base.css in the final output. this includes the
less-loader, and any others that inline
statements. while they de-dupe the files during the build, since
app.css are different entry points, the preprocessor has no way of knowing
about the shared files. when they output the css to webpack, there is no simple
way of telling webpack which dependencies are included in the compiled module.
you also have the development-time annoyance that since webpack doesn't see
these dependencies, making a change to
base.css won't trigger a
one approach for solving the dependency issue would be to just compile the
source, but not trace the dependencies in the preprocessor. this could be done
in less by using a
.css extension in the
or in rework by not including the import plugin.
now the problem becomes resolving variables. variables are especially hard to resolve at build time since they have a sort of cyclic dependency:
base.cssmight define a
--base-fontvariable and use it to set the default font for the app (like in SUIT CSS, for example)
base.css, so we need to know it's value in order to compile the
--base-font, so it depends on
app.cssmight also re-define
--base-font, so now in order to compile
base.css, we need that new value. now
this is only a problem because we're trying to resolve the values at build-time, but if we had css variable support in browsers it wouldn't be an issue (we don't though).
rework-webpack-loader solves this by going through all of the css files up
front and creating a mapping from variable names to values, and then using this
to resolve variables during compilation. the downside is that if you change
variable values, you need to restart the webpack dev server, but the upside is
that it handles css variables' cyclic dependencies.
to avoid an extra parse of the css. a little background on how webpack makes css work by default:
require's all of the things the css
style-loadertakes the name of a webpack module that returns a string, and creates a module that inserts a
<style>element into the document with the css string as its content
if we re-use
css-loader we're parsing/stringifying the css twice. admittedly
this is kind of a weak reason. especially since, if you want to add something
autoprefixer, you're going to have to parse the css
again anyway. you're probably better off optimizing the development build by
focusing on incrementally building small modules anyway.