SCSS Local Development with Webpack and Live Reload
If you have SCSS files in your project that you wish to work with during local development, a proposed solution using Webpack follows.
File structure
Suppose we have a directory scss-website
scss-website/
├── Dockerfile.bootstrap
├── Dockerfile.dev
├── assets
│ ├── js
│ │ └── index.js
│ └── scss
│ └── styling.scss
├── index.html
└── webpack.config.js
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<title>My website</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="assets/main.css">
</head>
<body>
<h1>Welcome user</h1>
<script src="assets/main.js"></script>
</body>
</html>
assets/scss/styling.scss
@import url('https://fonts.googleapis.com/css?family=Source+Serif+Pro');
$primary-font: 'Source Serif Pro', serif;
$primary-bg-colour: yellow;
$primary-colour: blue;
body {
font-family: $primary-font;
color: $primary-colour;
background-color: $primary-bg-colour;
}
Docker
- Install Docker and run the Docker daemon.
cd /path/to/scss-website
Bootstrap the repository
Dockerfile.bootstrap
FROM node:alpine
ARG PROJECT_DIR="/scss-website"
RUN npm install adddep -g
RUN mkdir $PROJECT_DIR
WORKDIR $PROJECT_DIR
CMD ["sh", \
"-c", \
"npm init --yes && adddep \
webpack \
webpack-bundle-tracker \
babel-cli \
babel-loader \
webpack-cli \
css-loader \
sass-loader \
style-loader \
node-sass \
webpack-dev-server \
mini-css-extract-plugin"]
We will create a package.json
with the dependencies
required to run Webpack without downloading any of them.
First, build the Docker image
docker build --tag scss-website-dev-bootstrap . --file Dockerfile.bootstrap
then run it
docker run --name scss-website-dev-bootstrap --volume $(pwd):/scss-website --rm scss-website-dev-bootstrap
There should now be a package.json
in the project root with the required dependencies as
specified in Dockerfile.bootstrap
.
Webpack configuration
webpack.config.js
const path = require('path');
const BundleTracker = require('webpack-bundle-tracker');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
context: __dirname,
devServer: {
host: '0.0.0.0',
port: 8000,
},
entry: {
main: './assets/js/index.js',
},
resolveLoader: {
modules: [path.resolve(__dirname, '..', 'package', 'node_modules')]
},
output: {
path: path.resolve('./assets/bundles/'),
publicPath: '/assets/',
filename: '[name].js',
},
plugins: [
new BundleTracker({filename: './webpack-stats.json'}),
new MiniCssExtractPlugin({
filename: '[name].css',
chunkFilename: '[id]-[hash].css',
}),
],
module: {
rules: [
{
test: /\.scss$/,
use: [
MiniCssExtractPlugin.loader,
'css-loader',
'sass-loader',
],
},
],
},
}
assets/js/index.js
import '../scss/styling.scss';
Build the Webpack Docker image
Dockerfile.dev
FROM node:alpine
ARG PROJECT_DIR="/scss-website"
ARG PACKAGE_DIR="/package"
ENV NODE_PATH /package/node_modules
ENV PATH="${PACKAGE_DIR}/node_modules/.bin:${PATH}"
RUN mkdir $PACKAGE_DIR
RUN mkdir $PROJECT_DIR
ADD package.json $PACKAGE_DIR
WORKDIR $PACKAGE_DIR
RUN npm install
WORKDIR $PROJECT_DIR
ADD . $PROJECT_DIR
EXPOSE 8000
CMD ["webpack-dev-server", "--mode development", "--color"]
Ensure in package.json
there is no /usr/local/bin/node
dependency. Then
docker build --tag scss-website-dev . --file Dockerfile.dev
Test local development
docker run --name scss-website-dev --volume $(pwd):/scss-website --publish 8000:8000 --rm scss-website-dev
- Navigate to
http://localhost:8000/
in a browser, you should see the contents ofindex.html
- Make a styling change in
assets/scss/styling.scss
- Styling change should show up automatically in the browser (initial change might require a manual refresh)