D
D
dark_king_132020-04-17 21:32:57
Express.js
dark_king_13, 2020-04-17 21:32:57

How to make HMR work for scss|sass if the server is on express?

Based on some tutorials from the network, I set up Hot Module Replacement for a project with a server on express.

hmr.ts
import { Application } from 'express'
const webpack = require('webpack')
const webpackDevConfig = require('../../../webpack/webpack.dev.conf')

const bundler = webpack(webpackDevConfig)

const webpackDevMiddleware = require('webpack-dev-middleware')(bundler, {
  stats: 'errors-warnings',
  hot: true,
})
const webpackHotMiddleware = require('webpack-hot-middleware')(bundler)

function hmr(app : Application) {
  app.use(webpackDevMiddleware)
  app.use(webpackHotMiddleware)
}

module.exports = hmr

index.ts
import { Application, Request, Response } from 'express'
import { Server as ServerIO } from 'socket.io'
import { Server } from 'http'
const fs = require('fs')
const path = require('path')
const http = require('http')
const express = require('express')
const consola = require('consola')
const socketIO = require('socket.io')
const bodyParser = require('body-parser')
const socketAction = require('./modules/socket.io')
require('dotenv').config()

function start () {
  try {
    const PORT : number|undefined = parseInt(process.env.PORT || '3000')
    const HOST : string|undefined = process.env.HOST || 'localhost'
    
    const PATH_TO_CLIENT : string  = path.join(__dirname, '..', '..', './dist')
    const PATH_TO_HTML  : string = path.join(PATH_TO_CLIENT, 'index.html')

    fs.stat(PATH_TO_HTML, (err : any) => {
      if (err && process.env.NODE_ENV === 'production') throw consola.error({message: 'index.html is not defined', badge: true,})
    })

    const app : Application = express()
    const server : Server = http.createServer(app)
    const io : ServerIO = socketIO.listen(server)

    app.use(express.static(PATH_TO_CLIENT))
    app.use(bodyParser.json())
    app.use(bodyParser.urlencoded({ extended: true }))
    if (process.env.NODE_ENV === 'development') require('./modules/hmr')(app)

    app.get('/', (req : Request, res : Response) => res.sendFile(PATH_TO_HTML))

    server.listen(PORT, HOST, () => consola.ready({
        message: `Server is listening to http://${HOST}:${PORT}`, badge: true, }))

    socketAction(io)

  } catch(err) { if (err)  consola.error({ message: `ERROR: ${err}`, badge: true, }) }
}

start()

webpack.dev.conf.js
const webpack =  require('webpack')
const merge = require('webpack-merge')
const baseWebpackConfig = require('./webpack.base.conf')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')

const devWebpackConfig = merge(baseWebpackConfig, {
  mode: 'development',
  devtool: 'cheap-module-eval-source-map',
  stats: 'errors-warnings',
  entry: {
    app: [
      'webpack-hot-middleware/client?path=/__webpack_hmr&reload=true',
      `${baseWebpackConfig.externals.paths.src}/index.tsx`,
    ],
  },
  output: {
    filename: `${baseWebpackConfig.externals.paths.assets}js/[name].[hash].bundle.js`,
  },
  module: {
    rules: [
      {
        test: /\.(png|jp(e)?g|gif|svg)$/,
        use: {
          loader: 'file-loader',
          options: {
            name: '[name].[ext]',
            outputPath: `${baseWebpackConfig.externals.paths.assets}img`,
            useRelativePath: true
          }
        },
      }, 
    ]
  },
  plugins: [
    new webpack.SourceMapDevToolPlugin({
      filename: '[file].map'
    }),
    new MiniCssExtractPlugin({
      filename: `${baseWebpackConfig.externals.paths.assets}css/[name].[hash].css`,
      chunkFilename: `${baseWebpackConfig.externals.paths.assets}css/[name].[hash].chunk.css`,
    }),
    new webpack.HotModuleReplacementPlugin(),
  ]
})

module.exports = devWebpackConfig

And everything seems to work, if I change something in scripts, or in Vue / React, the project is rebuilt and the data immediately changes on the page, but when I change css / sass / scsss, the project is rebuilt, but the page is not reloaded and the data is not are updated. You have to reboot to see the changes.
How can I make sure that when changing styles, the page is also updated?

Answer the question

In order to leave comments, you need to log in

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question