frontend/seed/scripts/start.js
2025-05-14 21:49:03 +02:00

128 lines
4.2 KiB
JavaScript

const webpack = require('webpack');
const nodemon = require('nodemon');
const rimraf = require('rimraf');
// webpack-dev-middleware is a wrapper that will emit files processed by webpack to a server. This is used in webpack-dev-server internally, however it's available as a separate package to allow more custom setups if desired.
const webpackDevMiddleware = require('webpack-dev-middleware');
const webpackHotMiddleware = require('webpack-hot-middleware');
const express = require('express');
const clientConfig = require('../config/webpack/ssr/client.js')();
const serverConfig = require('../config/webpack/ssr/server.js')();
const paths = require('../config/paths');
const { logMessage, compilerPromise } = require('./utils');
const app = express();
// Example commands :
// cross-env NODE_ENV=development PORT=5000 node scripts/start.js
const WEBPACK_PORT = process.env.WEBPACK_PORT || (!isNaN(Number(process.env.PORT)) ? Number(process.env.PORT) + 1 : 8501);
const start = async () => {
// Remove folders
rimraf.sync(paths.clientBuild);
rimraf.sync(paths.serverBuild);
// Add the client which connects to our middleware
// You can use full urls like 'webpack-hot-middleware/client?path=http://localhost:3000/__webpack_hmr'
// useful if you run your app from another point like django
clientConfig.entry.bundle = [`webpack-hot-middleware/client?path=http://localhost:${WEBPACK_PORT}/__webpack_hmr`, ...clientConfig.entry.bundle];
// Customize the main hot update filename. create an history in the client output folder
clientConfig.output.hotUpdateMainFilename = 'updates/[hash].hot-update.json';
clientConfig.output.hotUpdateChunkFilename = 'updates/[id].[hash].hot-update.js';
// Allow hot reload (if path was relative, no need to add those)
const publicPath = clientConfig.output.publicPath;
clientConfig.output.publicPath = [`http://localhost:${WEBPACK_PORT}`, publicPath].join('/').replace(/([^:+])\/+/g, '$1/');
serverConfig.output.publicPath = [`http://localhost:${WEBPACK_PORT}`, publicPath].join('/').replace(/([^:+])\/+/g, '$1/');
// Combine compilers
const multiCompiler = webpack([clientConfig, serverConfig]);
const clientCompiler = multiCompiler.compilers.find(compiler => compiler.name === 'client');
const serverCompiler = multiCompiler.compilers.find(compiler => compiler.name === 'server');
// Make sure to know when the compilation is done
const clientPromise = compilerPromise('client', clientCompiler);
const serverPromise = compilerPromise('server', serverCompiler);
// Stats need be to explored
const watchOptions = {
// poll: true,
ignored: /node_modules/,
stats: clientConfig.stats,
};
app.use((req, res, next) => {
res.header('Access-Control-Allow-Origin', '*');
return next();
});
app.use(
// Tell express to use the webpack-dev-middleware and use the webpack.config.js
// configuration file as a base.
webpackDevMiddleware(clientCompiler, {
publicPath: clientConfig.output.publicPath,
stats: clientConfig.stats,
watchOptions,
}),
);
app.use(webpackHotMiddleware(clientCompiler));
app.listen(WEBPACK_PORT);
// Here we use simply the watch of webpack
serverCompiler.watch(watchOptions, (error, stats) => {
if (!error && !stats.hasErrors()) {
console.log(stats.toString(serverConfig.stats));
return;
}
if (error) {
logMessage(error, 'error');
}
if (stats.hasErrors()) {
const info = stats.toJson();
const errors = info.errors[0].split('\n');
logMessage(errors[0], 'error');
logMessage(errors[1], 'error');
logMessage(errors[2], 'error');
}
});
// wait until client and server is compiled
try {
await serverPromise;
await clientPromise;
} catch (error) {
logMessage(error, 'error');
}
const script = nodemon({
script: `${paths.serverBuild}/server.js`,
ignore: ['src', 'scripts', 'config', './*.*', 'build/client'],
});
script.on('restart', () => {
logMessage('Server side app has been restarted.', 'warning');
});
script.on('quit', () => {
console.log('Process ended');
process.exit();
});
script.on('error', () => {
logMessage('An error occured. Exiting', 'error');
process.exit(1);
});
};
start();