I am trying to configure a live reload using Rails 7.1.3, esbuild and .scss files.
This is my esbuild.config.js file:
require('dotenv').config();
const esbuild = require('esbuild');
const chokidar = require('chokidar');
const http = require('http');
const path = require('path');
const isProduction = process.env.RAILS_ENV === 'production';
const watchMode = process.argv.includes('--watch') || process.argv.includes('--reload');
const reloadMode = process.argv.includes('--reload');
const port = 3030;
const esbuildConfig = {
entryPoints: [path.join('app/javascript', 'application.js')],
bundle: true,
minify: isProduction,
sourcemap: !isProduction,
target: 'es2015',
outdir: path.join('app/assets/builds'),
};
esbuild.build(esbuildConfig).then(() => {}).catch(() => process.exit(1));
let clients = [];
let clientId = 0;
const server = http.createServer((req, res) => {
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', 'GET, OPTIONS');
res.setHeader('Access-Control-Allow-Headers', 'Content-Type');
res.writeHead(200, {
'Content-Type': 'text/event-stream',
'Cache-Control': 'no-cache',
'Connection': 'keep-alive',
});
const thisClientId = clientId++;
clients[thisClientId] = res;
req.on('close', () => {
delete clients[thisClientId];
});
});
server.listen(port, () => {
console.log(`Server listening on port ${port}`);
});
chokidar.watch([
'app/javascript/**/*',
'app/views/**/*',
'app/assets/stylesheets/**/*',
]).on('all', () => {
esbuild.build(esbuildConfig).then(() => {
clients.forEach((res) => {
res.write('data: update\n\n');
});
}).catch(() => process.exit(1));
});
And this is part of my package.json:
"scripts": {
"build": "node esbuild.config.js",
"build:css:compile": "sass ./app/assets/stylesheets/application.bootstrap.scss:./app/assets/builds/application.css --no-source-map --load-path=node_modules",
"build:css:prefix": "postcss ./app/assets/builds/application.css --use=autoprefixer --output=./app/assets/builds/application.css",
"build:css": "yarn build:css:compile && yarn build:css:prefix",
"watch:css": "nodemon --watch ./app/assets/stylesheets/ --ext scss --exec \"yarn build:css\""
},
I have a live_reload.js file:
if (process.env.NODE_ENV === 'development') {
const eventSource = new EventSource('http://localhost:3030');
eventSource.onmessage = (event) => {
if (event.data === 'update') {
window.location.reload();
}
};
}
And everything work fine, but the main problem is that when I do a change in a .scss file it takes times to build the .css and before it finish the process my page already reloaded.
And this is my Procfile.dev file:
css: yarn watch:css
web: env RUBY_DEBUG_OPEN=true bin/rails server
worker: bundle exec sidekiq -C config/sidekiq.yml
js: yarn build --watch
I tried using LiveReload plugin but it doesn't reloead the page.
And also running my app using overmind but still having the same behavior that reload the page before the .css process is over.
And I don't wnat to use webpacker because has been retired.
What can I do to solve that?