Webpack allows specifying multiple entry points, for example, to compile multiple JavaScript files via Babel. This post shows how to compile SASS to its own file when using various entry points.
The problem
Until now, I always had something like that as the entry
in my Webpack config:
entry: ['./assets/src/js/functions.js', './assets/src/scss/frontend.scss', './assets/src/scss/editor.scss'],
Code language: JavaScript (javascript)
With various loaders, I compiled the JavaScript via Babel to a functions.js
and the SASS files to the CSS files frontend.css
and editor.css
. Now I wanted to add a second JavaScript file as an entry, which should be compiled to a separate file. The Webpack documentation on entry points shows how to define multiple entry points, and that was my first attempt:
entry: {
functions: './assets/src/js/functions.js',
glide: './assets/src/js/glide.js',
frontend: './assets/src/scss/frontend.scss',
editor: './assets/src/scss/editor.scss',
},
Code language: JavaScript (javascript)
That worked somehow but had its problems. For every CSS file, I got a JavaScript file with the same name. Theoretically, I could ignore them, but that would not be very satisfying.
The solution
In the afterthought, the solution is relatively simple: I write the SASS files in an array with one of the JavaScript files and get my wanted solution of two JavaScript and two CSS files.
entry: {
functions: ['./assets/src/js/functions.js', './assets/src/scss/frontend.scss', './assets/src/scss/editor.scss'],
glide: './assets/src/js/glide.js',
},
Code language: JavaScript (javascript)
That could be a Webpack 4 config file with the solution:
const path = require('path');
module.exports = {
mode: 'development',
entry: {
functions: ['./assets/src/js/functions.js', './assets/src/scss/frontend.scss', './assets/src/scss/editor.scss'],
glide: './assets/src/js/glide.js',
},
output: {
path: path.resolve(__dirname, 'assets'),
filename: 'dist/js/[name].js',
},
module: {
rules: [
/**
* Running Babel on JS files.
*/
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
plugins: ['lodash'],
presets: ['@wordpress/default']
}
}
},
{
test: /\.scss$/,
use: [
{
loader: 'file-loader',
options: {
name: 'dist/css/[name].css',
}
},
{
loader: 'extract-loader'
},
{
loader: 'css-loader?-url'
},
{
loader: 'postcss-loader'
},
{
loader: 'sass-loader'
}
]
}
]
},
};
Code language: JavaScript (javascript)
Here are the devDependencies
from my package.json
(more than needed for that example):
"devDependencies": {
"@wordpress/babel-preset-default": "^1.3.0",
"autoprefixer": "^8.5.0",
"babel-core": "^6.26.0",
"babel-loader": "^7.1.2",
"babel-preset-env": "^1.6.0",
"css-loader": "^0.28.7",
"extract-loader": "^2.0.1",
"file-loader": "^1.1.11",
"lodash-webpack-plugin": "^0.11.5",
"node-sass": "^4.9.0",
"postcss-cli": "^5.0.0",
"postcss-loader": "^2.0.6",
"sass-loader": "^7.0.1",
"svg-spritemap-webpack-plugin": "^2.6.0",
"svgo": "^1.0.5",
"svgo-loader": "^2.1.0",
"webpack": "^4.8.3",
"webpack-cli": "^3.0.8"
},
Code language: JSON / JSON with Comments (json)
And that is the content of my postcss.config.js
:
module.exports = {
plugins: {
autoprefixer: { browsers: ['last 2 versions'], grid: true }
}
}
Code language: JavaScript (javascript)
It's really helpfull. I was read webpack.js.org docs but it's difficult. Thank u.
You’re welcome, I’m happy to hear that it was helpful!
I have been trying to learn Webpack, and was trying to resolve this scenario. But no luck. I have been using mini-css-extract-plugin, sass-loader, css-loader and style-loader, and not using postCss and file loader, something like this " loader: [miniCss.loader, "css-loader", "sass-loader"] ". Can you tell me which plugin or settings forces webpack to extract multiple css files as in your example.
Hi,
sorry, but I am not that deep into webpack, I am using the config that is explained in the article and am happy that it works 😬
Best,
Florian
I just succeed by adding file-loader.