Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit a084c11

Browse files
committedFeb 21, 2025
feat(create-plugin): add basic rspack live reload plugin
1 parent 9038405 commit a084c11

File tree

2 files changed

+115
-1
lines changed

2 files changed

+115
-1
lines changed
 
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
const path = require('path');
2+
const WebSocket = require('ws');
3+
const http = require('http');
4+
5+
class RspackLiveReloadPlugin {
6+
constructor(options = {}) {
7+
this.options = Object.assign(
8+
{
9+
port: 35729,
10+
delay: 0,
11+
appendScriptTag: true,
12+
protocol: 'http',
13+
},
14+
options
15+
);
16+
}
17+
18+
apply(compiler) {
19+
const isRspack = compiler.getInfrastructureLogger !== undefined;
20+
console.log(compiler)
21+
if (!isRspack) {
22+
throw new Error('This plugin is designed to work with Rspack 1');
23+
}
24+
25+
compiler.hooks.afterEmit.tap('RspackLiveReloadPlugin', (compilation) => {
26+
this._startServer();
27+
this._notifyClient();
28+
});
29+
30+
compiler.hooks.done.tap('RspackLiveReloadPlugin', (stats) => {
31+
if (this.options.appendScriptTag) {
32+
this._injectLiveReloadScript(stats.compilation);
33+
}
34+
});
35+
}
36+
37+
_startServer() {
38+
if (this.server) {
39+
return;
40+
}
41+
42+
const port = this.options.port;
43+
44+
this.httpServer = http.createServer((req, res) => {
45+
if (req.url === '/livereload.js') {
46+
res.writeHead(200, { 'Content-Type': 'application/javascript' });
47+
res.end(this._getLiveReloadScript());
48+
} else {
49+
res.writeHead(404);
50+
res.end('Not Found');
51+
}
52+
});
53+
54+
this.server = new WebSocket.Server({ server: this.httpServer });
55+
this.httpServer.listen(port, () => {
56+
console.log(`LiveReload server started on http://localhost:${port}`);
57+
});
58+
}
59+
60+
_notifyClient() {
61+
if (!this.server) {
62+
return;
63+
}
64+
65+
this.server.clients.forEach((client) => {
66+
if (client.readyState === WebSocket.OPEN) {
67+
client.send(JSON.stringify({ action: 'reload' }));
68+
}
69+
});
70+
}
71+
72+
_injectLiveReloadScript(compilation) {
73+
compilation.hooks.processAssets.tap(
74+
{
75+
name: 'RspackLiveReloadPlugin',
76+
stage: compilation.PROCESS_ASSETS_STAGE_ADDITIONAL,
77+
},
78+
(assets) => {
79+
Object.keys(assets).forEach((filename) => {
80+
if (path.extname(filename) === '.html') {
81+
const assetSource = compilation.getAsset(filename).source;
82+
const updatedSource = assetSource
83+
.source()
84+
.replace('</body>', `<script src="http://localhost:${this.options.port}/livereload.js"></script></body>`);
85+
compilation.updateAsset(filename, {
86+
source: () => updatedSource,
87+
size: () => updatedSource.length,
88+
});
89+
}
90+
});
91+
}
92+
);
93+
}
94+
95+
_getLiveReloadScript() {
96+
return `
97+
(function() {
98+
if (typeof WebSocket === 'undefined') return;
99+
const ws = new WebSocket('${this.options.protocol}://localhost:${this.options.port}');
100+
ws.onmessage = function(event) {
101+
const data = JSON.parse(event.data);
102+
if (data.action === 'reload') {
103+
window.location.reload();
104+
}
105+
};
106+
})();
107+
`;
108+
}
109+
}
110+
111+
module.exports = RspackLiveReloadPlugin;

‎packages/create-plugin/templates/common/.config/rspack/rspack.config.ts

+4-1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import path from 'path';
1212
import ReplaceInFileWebpackPlugin from 'replace-in-file-webpack-plugin';
1313
import TerserPlugin from 'terser-webpack-plugin';
1414
import { RspackVirtualModulePlugin } from 'rspack-plugin-virtual-module';
15+
import RspackLiveReloadPlugin from './liveReloadPlugin';
1516

1617
import { DIST_DIR, SOURCE_DIR } from './constants';
1718
import { getCPConfigVersion, getEntries, getPackageJson, getPluginJson, hasReadme, isWSL } from './utils';
@@ -224,7 +225,7 @@ const config = async (env): Promise<Configuration> => {
224225
]),
225226
...(env.development
226227
? [
227-
// new LiveReloadPlugin(), Unsupported in rspack.
228+
new RspackLiveReloadPlugin(),
228229
new ForkTsCheckerWebpackPlugin({
229230
async: Boolean(env.development),
230231
issue: {
@@ -254,6 +255,8 @@ const config = async (env): Promise<Configuration> => {
254255
};
255256
}
256257

258+
259+
257260
return baseConfig;
258261
};
259262

0 commit comments

Comments
 (0)
Please sign in to comment.