Webpack style-loader vs css-loader
WebpackWebpack Style-LoaderWebpack Problem Overview
I have two questions.
- CSS Loader and Style Loader are two webpack loaders. I couldn't grasp the difference between the two. Why do I have to use two loaders when they both do the same job?
- What is this .useable.less and .useable.css mentioned in the above Readme.md files?
Webpack Solutions
Solution 1 - Webpack
The CSS loader takes a CSS file and returns the CSS with imports
and url(...)
resolved via webpack's require
functionality:
> var css = require("css!./file.css"); > // => returns css code from file.css, resolves imports and url(...)
It doesn't actually do anything with the returned CSS.
The style loader takes CSS and actually inserts it into the page so that the styles are active on the page.
They perform different operations, but it's often useful to chain them together, like Unix pipes. For example, if you were using the Less CSS preprocessor, you could use
require("style!css!less!./file.less")
to
- Turn
file.less
into plain CSS with the Less loader - Resolve all the
imports
andurl(...)
s in the CSS with the CSS loader - Insert those styles into the page with the style loader
Solution 2 - Webpack
css-loader
reads in a css file as a string. You could replace it with raw-loader
and get the same effect in a lot of situations. Since it just reads the file contents and nothing else, it's basically useless unless you chain it with another loader.
style-loader
takes those styles and creates a <style>
tag in the page's <head>
element containing those styles.
If you look at the javascript inside bundle.js
after using style-loader
you'll see a comment in the generated code that says
> // style-loader: Adds some css to the DOM by adding a
Solution 3 - Webpack
To answer the second question "What is this .useable.less and .useable.css mentioned in the above Readme.md files?", by default when a style is require'd
, the style-loader module automatically injects a <script>
tag into the DOM, and that tag remains in the DOM until the browser window is closed or reloaded. The style-loader module also offers a so-called "reference-counted API" that allows the developer to add styles and remove them later when they're no longer needed. The API works like this:
const style = require('style/loader!css!./style.css')
// The "reference counter" for this style starts at 0
// The style has not yet been injected into the DOM
style.use() // increments counter to 1, injects a <style> tag
style.use() // increments counter to 2
style.unuse() // decrements counter to 1
style.unuse() // decrements counter to 0, removes the <style> tag
By convention, style sheets loaded using this API have an extension ".usable.css" rather than simply ".css" as above.
Solution 4 - Webpack
Let me answer 1) from your question. What is the difference between style-loader
and css-loader
? Or: what do they do?
- there are different incompatible module import mechanisms in Javascript
- webpack allows, rewrites and extends all well known module import mechanisms
- normally only Javascript can be imported
- with loaders, webpack also allows other files to be imported
- if you start using that feature, that Javascript can not be used unmodified without webpack any more
- the loader decides
- if additional files appears in the output directory (usually not)
- what to “return”
- loaders can be chained
- the output of the last loader will be included in the bundle
- the last loader needs to return Javascript, otherwise the bundled Javascript will be faulty
- imports which end with the
css-loader
will receive an array in Javascript- I could not find proper documentation what you will receive
- the array seems to contain one element for each CSS file processed (e.g. with CSS
@import
rules), having the file name and file content (modified) as strings - no extra files will end up in the output directory
- if you use the
css-loader
alone, then you have to do something with the strings yourself or they just increase your bundle size for nothing
style-loader
will wrap Javascript fromcss-loader
in more Javascript- it can not and does not read CSS files
- the wrapping creates
<style>
elements with the CSS strings fromcss-loader
and injects them in the DOM style-loader
can not be used alone (you get an error), because it doesn’t read files and expectscss-loader
-like Javascript as input
Solution 5 - Webpack
Webpack documentation recommends to combine style-loader with css-loader: