Style Only Entries with Webpack and Sass

program script digital wallpaper
Photo by Maik Jonietz on Unsplash

Sometimes you just want to use Webpack for style-only entries. While this tutorial is mostly for my sanity (I have to look this up all the time), I thought I’d share it in case others have the same issue.

Webpack is generally used for JavaScript only, however you can configure it to accept only SCSS files.

Project Structure

Here’s a very simple project structure. The Ascii folder structure is courtesy of the Ascii Tree Generator.

src/
├─ scss/
│  ├─ admin.scss
│  ├─ frontend.scss
package.json
webpack.config.jsCode language: AsciiDoc (asciidoc)

Webpack Config

As of this writing, this technique only works with Webpack ~4.0. I’ll share my package.json in a bit. Let’s dive into the Webpack config.

const path = require('path');
const FixStyleOnlyEntriesPlugin = require('webpack-fix-style-only-entries');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');

module.exports = [
	{
		mode: process.env.NODE_ENV,
		entry: {
			'sce-admin': ['./src/scss/admin.scss'],
			'sce-frontend': ['./src/scss/frontend.scss'],
		},
		output: {},
		module: {
			rules: [
				{
					test: /\.scss$/,
					exclude: /(node_modules|bower_components)/,
					use: [
						{
							loader: MiniCssExtractPlugin.loader,
						},
						{
							loader: 'css-loader',
							options: {
								sourceMap: true,
								url: false,
							},
						},
						'sass-loader',
					],
				},
			],
		},
		devtool: 'source-map',
		plugins: [new FixStyleOnlyEntriesPlugin(), new MiniCssExtractPlugin()],
	},
];
Code language: JavaScript (javascript)

Let’s dive into some dependencies.

const path = require('path');
const FixStyleOnlyEntriesPlugin = require('webpack-fix-style-only-entries');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');Code language: JavaScript (javascript)

The obvious dependencies are webpack-fix-style-only-entries and mini-css-extract-plugin. We’ll need both.

  1. The mini-css-extract-plugin will create a new file per scss file.
  2. The webpack-fix-style-only-entries will remove the JS file for each stylesheet.

By default, Webpack will create a JS file for each stylesheet endpoint. We use the webpack-fix-style-only-entries to get around this.

Let’s dive into the next webpack section.

module.exports = [
	{
		mode: process.env.NODE_ENV,
		entry: {
			'sce-admin': ['./src/scss/admin.scss'],
			'sce-frontend': ['./src/scss/frontend.scss'],
		},
		output: {},
Code language: JavaScript (javascript)

We set our environment variables, set the entry points (highlighted), and choose not to output anything.

So far so good.

module: {
	rules: [
		{
			test: /\.scss$/,
			exclude: /(node_modules|bower_components)/,
			use: [
				{
					loader: MiniCssExtractPlugin.loader,
				},
				{
					loader: 'css-loader',
					options: {
						sourceMap: true,
						url: false,
					},
				},
				'sass-loader',
			],
		},
	],
},
Code language: JavaScript (javascript)

I have highlighted the important parts.

  1. We test for SCSS files.
  2. We exclude node_modules.
  3. We use the MiniCssExtractPlugin to create the separate files and also to minify the output for production use.
  4. sass-loader and css-loader are needed to process the SCSS files.

I apologize for not being more descriptive above. Some of these dependencies were a result of trial-and-error.

Finally, we initialize a source map and define our plugins.

devtool: 'source-map',
plugins: [new FixStyleOnlyEntriesPlugin(), new MiniCssExtractPlugin()],Code language: JavaScript (javascript)

For convenience, here is the entire Webpack file again:

const path = require('path');
const FixStyleOnlyEntriesPlugin = require('webpack-fix-style-only-entries');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');

module.exports = [
	{
		mode: process.env.NODE_ENV,
		entry: {
			'sce-admin': ['./src/scss/admin.scss'],
			'sce-frontend': ['./src/scss/frontend.scss'],
		},
		output: {},
		module: {
			rules: [
				{
					test: /\.scss$/,
					exclude: /(node_modules|bower_components)/,
					use: [
						{
							loader: MiniCssExtractPlugin.loader,
						},
						{
							loader: 'css-loader',
							options: {
								sourceMap: true,
								url: false,
							},
						},
						'sass-loader',
					],
				},
			],
		},
		devtool: 'source-map',
		plugins: [new FixStyleOnlyEntriesPlugin(), new MiniCssExtractPlugin()],
	},
];Code language: JavaScript (javascript)

I’m sure you groovy JavaScript/Webpack devs can make this snippet better. I say, have at it.

Package.json

Here’s a sample package.json file I use for a plugin called Simple Comment Editing (GitHub).

{
  "name": "simple-comment-editing",
  "version": "3.0.0",
  "description": "Simple Comment Editing for your users",
  "main": "gruntfile.js",
  "scripts": {
    "start": "webpack --watch --mode development",
    "dev": "webpack --mode development",
    "build": "webpack --mode production",
    "lint": "eslint ."
  },
  "repository": {
    "type": "git",
    "url": "git+https://github.com/MediaRon/simple-comment-editing.git"
  },
  "keywords": [
    "comment",
    "editing",
    "simple",
    "comment",
    "editing"
  ],
  "author": "Ronald Huereca",
  "license": "GPL-3.0-or-later",
  "bugs": {
    "url": "https://github.com/MediaRon/simple-comment-editing/issues"
  },
  "homepage": "https://github.com/MediaRon/simple-comment-editing#readme",
  "devDependencies": {
    "css-loader": "^5.2.6",
    "grunt": "^1.4.0",
    "grunt-cli": "^1.4.2",
    "grunt-contrib-compress": "^2.0.0",
    "mini-css-extract-plugin": "^1.6.0",
    "sass-loader": "^10.0.5",
    "style-loader": "^2.0.0",
    "webpack": "^4.42.0",
    "webpack-cli": "^4.5.0",
    "webpack-fix-style-only-entries": "^0.6.1"
  },
  "dependencies": {
    "sass": "^1.34.0"
  }
}Code language: JavaScript (javascript)

Download a Sample ZIP
(Sample SCSS files included. Pardon my horrible SCSS skills).

If you choose to use the above package.json, you’re welcome to rename the objects to make it your own.

After that, just run npm install inside the project directory and you should be set.

  • Start watching your SCSS files by running: npm run start
  • Run the dev SCSS by running: npm run dev
  • And finally, when you’re done, run: npm run build

For example, when I run npm run start, I receive the following output:

Webpack Command Line Output
Webpack Command Line Output

That’s it!

If all is well, you’ll end up with this folder structure.

dist/
├─ sce-admin.css
├─ sce-admin.css.map
├─ sce-frontend.css
├─ sce-frontend.css.map
src/
├─ scss/
│  ├─ admin.scss
│  ├─ frontend.scss
package.json
webpack.config.js
Code language: AsciiDoc (asciidoc)

Questions?

Please leave a comment below and I’ll do my best to respond and/or update the article with more information.

Thank you for reading.

Ronald Huereca
Ronald Huereca

Ronald Huereca

Ronald has been part of the WordPress community since 2006, starting off writing and eventually diving into WordPress plugin development and writing tutorials and opinionated pieces.

No stranger to controversy and opinionated takes on tough topics, Ronald writes honestly when he covers a topic.

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Ronald Huereca
MediaRon - Ronald Huereca

Ronald created MediaRon in 2011 and has more than fifteen years of releasing free and paid WordPress plugins.

Quick Links

Say Hi