Testing SCSS Locally: How to Build a Simple Node-based Playground
Today I want to describe to you how to build a simple and flexible playground to test SCSS code locally — if you are a DIYer there are good chances you'll enjoy the post.
There are a number of online services that let us run SCSS code on-the-fly, but at times none of them can replace the convenience offered by an offline playground. That's why today I want to describe to you how to build a simple and flexible playground to test SCSS code locally — if you are a DIYer there are good chances you'll enjoy the post.
The playground in question is a simple web server relying on Node.js. In particular we will build it using the Express.js framework and a few other packages. The playground will not only be able to run our SCSS, but also to automatically rerun it when we save changes and to refresh the browser's page without having to manually launch a reload.
If you never heard of Express.js don't worry, because I'll provide enough explanations to let you understand what the code does. However, even if your daily meal is front-end development, having a smattering on how to build a Node-based web server can be a game changer in your career. So I strongly encourage you to take some time to get familiar with the Express.js framework, if you haven't already.
First, Let's Create a package.json
Have you already created a new folder for our playground, by any chance? Not yet? Well, this is the right time to do it. I named mine scss-playground
, but you can choose another name if you wish.
Now, with your shell application, navigate to the just created folder and launch the initialisation of the package.json
file as shown below:
1cd path-to/scss-playground
2npm init
You can safely go through the creation of the package.json
file by leaving unchanged the default values. At the end of the process, the generated package.json
should have a content similar to this:
1{
2 "name": "scss-playground",
3 "version": "1.0.0",
4 "description": "",
5 "main": "index.js",
6 "scripts": {
7 "test": "echo \"Error: no test specified\" && exit 1"
8 },
9 "author": "",
10 "license": "ISC"
11}
Building the Playground
With a package.json
at hand, the dependencies needed by our playground can be installed without any trouble. First however, I would like to tell you about the other three files required by our app, so please create the following files and folders in the same directory as our package.json
:
1- index.js
2- package.json
3+ public
4 - index.html
5+ styles
6 - main.scss
index.js
will contain all the JavaScript needed to create, deal with and launch our web server.public/index.html
is where you can write your markup, the one on which to apply the SCSS rules you want to test.- And finally,
styles/main.scss
is where to place your SCSS code.
The dependencies I was referring to can be installed with the following npm
command:
1npm install express sass concurrently
As you can see, they are three:
- express is the Node-based framework I chose to streamline the server-related code.
- sass will be responsible to process your SCSS code and watch for changes to the
main.scss
file. - concurrently is an utility to run multiple shell commands in parallel.
About the install command, one might argue by saying that sass
and concurrently
are development dependencies and they should be installed as such — with the --save-dev
option — and it would be a correct remark, since they are tools needed only during development. The reason why we are installing them as production dependencies is to keep things as simple as possible, after all our playground isn't an app thought to be released to the public.
For the same reason we are going to keep the code needed to create our web server as minimal as possible, so the following goes into the index.js
file of our playground:
1const express = require( "express" );
2
3const port = 3000;
4const publicPath = ( __dirname + "/public" );
5
6const app = express();
7
8app.use( "/", express.static( publicPath ) );
9
10app.listen( port, () => {
11 console.log( `Server running: http://localhost:${port}` );
12});
Without going into too much detail, the snippet above does the following:
- Creates an Express web server.
- Through the
express.static()
middleware, instructs the server to serve all the files in ourpublic
folder without any prior processing, as static files. - Launches the web server on port 3000.
The next step to take is to update the scripts
property of our package.json
as follows:
1{
2 "name": "scss-playground",
3 "version": "1.0.0",
4 "description": "",
5 "scripts": {
6 "start": "node .",
7 "sass": "sass --watch styles/main.scss public/styles.css",
8 "dev": "concurrently 'npm start' 'npm run sass'"
9 },
10 "author": "",
11 "license": "ISC",
12 "dependencies": {
13 "concurrently": "^8.2.2",
14 "express": "^4.19.2",
15 "sass": "^1.77.1"
16 }
17}
To make everything more readable, I split the custom script we need into three separate ones:
- start tells Node to execute our
index.js
. - sass transforms our
main.scss
file into a browser-friendlystyles.css
style-sheet that will be saved into ourpublic
folder. Also, the--watch
option ensures that any changes tomain.scss
will automatically trigger an update of thepublic/styles.css
style-sheet. - Finally, dev is the script we will use to give life to our playground. It uses the
concurrently
utility to run thestart
andsass
scripts in parallel.
Running the First Test
Now our playground needs only some testing code. You can use the following code as the content of your public/index.html
document:
1<!DOCTYPE html>
2<html lang="en">
3<head>
4 <meta charset="UTF-8">
5 <meta name="viewport" content="width=device-width, initial-scale=1.0">
6 <title>SCSS Playground</title>
7 <link rel="stylesheet" href="styles.css" />
8</head>
9<body>
10 <p>Hello world!</p>
11</body>
12</html>
An important reminder: as highlighted in the snippet above, our index.html
document must include a link to the styles.css
file generated by sass
, otherwise no styling will appear in the browser.
All right, let's proceed.
To run your first test you just need to include a SCSS snippet like the following, for instance, in your styles/main.scss
file...
1$font-weight-semibold: 600;
2
3body {
4 font-weight: $font-weight-semibold;
5}
...and launch the dev
script:
1npm run dev
It's that easy.
Right now however, if you try to make some changes to your main.scss
and then you save them, you'll notice that the web page doesn't automatically refresh. This is because something is still missing, and that something is called LiveReload.
Live Refreshes on Saving Changes
LiveReload for Node.js is the tool without which our playground cannot automatically refresh the browser's page.
To integrate LiveReload into our playground, we first need to install the required packages:
1npm install livereload connect-livereload
And then write a few more lines of JavaScript into our index.js
script. Namely, the instructions highlighted in the snippet below:
1const express = require( "express" );
2const livereload = require( "livereload" );
3const connectLivereload = require( "connect-livereload" );
4
5const port = 3000;
6const publicPath = ( __dirname + "/public" );
7
8const app = express();
9const livereloadServer = livereload.createServer();
10
11livereloadServer.watch( publicPath );
12
13app.use( connectLivereload() );
14app.use( "/", express.static( publicPath ) );
15
16app.listen( port, () => {
17 console.log( `Server running: http://localhost:${port}` );
18});
What we are doing with the new lines of code is this:
- First we create a LiveReload server.
- Then we instruct the LiveReload server to watch for any changes occurring in our
public
folder — remember that thestyles.css
style-sheet, resulting from the processing ofmain.scss
, is saved to thepublic
folder. - And lastly, we ask our Express server to apply the
connectLivereload()
middleware, which makes all the browser-refresh-magic happen.
Just a closing note: for the live refreshes to take place, you need to restart the playground, by stopping the Express server (CTRL + C
) and relaunching it with a new npm run dev
.
Conclusion
As you will find out by using it, the playground, such as it is, can be used not just to test snippets of SCSS, but also entire style-sheets imported in the main.scss
file. And the good news is that this is possible without having to sacrifice the live-refresh feature offered by LiveReload.
Now you just have to make your SCSS shine!