Introduction
Webpack is mainly a JavaScript-bundler. Its "native" language is JavaScript and every other source requires a loader which transforms it to JavaScript. If you require()
an html-file for example...
var template = require("./some-template.html");
...you'll need the html-loader. It turns...
<div>
<img src="./assets/img.png">
</div>
...into...
module.exports = "<div>
<img src="" + require("./assets/img.png") + "">
</div>";
If a loader doesn't return JavaScript, it needs to be "piped" to another loader.
How to load SASS-files
Configure loaders
In order to use SASS you'll need at least the sass-loader and the css-loader. The css-loader returns a JavaScript string. If you want to import the returned JavaScript string as StyleSheet, you'll also need the style-loader.
Run npm i sass-loader css-loader style-loader --save
Now you need to apply these loaders on all files that match /.scss$/
:
// webpack.config.js
...
module: {
loaders: [
// the loaders will be applied from right to left
{ test: /.scss$/, loader: "style!css!sass" }
]
}
...
You can also pass options to node-sass as query parameters:
{
test: /.scss$/, loader: "style!css!sass?includePaths[]=" +
path.resolve(__dirname, "./bower_components/bootstrap-sass/assets/stylesheets/"
}
Since bootstrap references icons via the url()
statement, the css-loader will try to include these assets into the bundle and will throw an exception otherwise. That's why you'll also need the file-loader:
// webpack.config.js
...
module: {
loaders: [
{ test: /.scss$/, loader: "style!css!sass" },
{ test: /.jpe?g$|.gif$|.png$|.svg$|.woff$|.ttf$/, loader: "file" },
]
}
...
Configure entry
To include bootstrap into your bundle there are several ways. One is via the multi-entry option as you've already tried. I recommend to use a single entry where you require()
your main sass-file:
// main.js
require("./main.scss");
Given that your includePaths
are configured then you can do:
// main.scss
// Set the font path so that url() points to the actual file
$icon-font-path: "../../../fonts/bootstrap";
@import "bootstrap";
Please note that import statements inside scss-files are not touched by webpack because libsass has no api (yet) to provide custom resolvers.
To prevent code duplication it's also important to have a single main sass-file, because webpack compiles every sass-file individually.
With the coffee-loader installed via npm your final webpack.config.js
should look like:
module.exports = {
entry: "./js/main.coffee",
output: {
path: __dirname,
filename: "main.js"
},
module: {
loaders: [
{ test: /.scss$/, loader: "style!css!sass" },
{ test: /.jpe?g$|.gif$|.png$|.svg$|.woff$|.ttf$/, loader: "file" },
{ test: /.coffee$/, loader: "coffee" }
]
}
};
Webpack globally?
It's best not to install webpack globally, because it's a dependency of your project and thus should be controlled via npm. You can use the scripts-section of your package.json
:
{
...
"scripts": {
"start": "webpack --config path/to/webpack.config.js & node server.js"
}
}
Then you just need to run npm start