Skip to content

Commit 4af6bfe

Browse files
committed
Change webpack to rsbuild
Signed-off-by: Denis Bykhov <bykhov.denis@gmail.com>
1 parent e778a27 commit 4af6bfe

10 files changed

Lines changed: 1393 additions & 288 deletions

File tree

common/config/rush/pnpm-lock.yaml

Lines changed: 732 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

common/scripts/docker_patch.sh

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,10 @@ fi
3535

3636
export DOCKER_VERSION="$VERSION"
3737
export DOCKER_EXTRA="--platform=$PLATFORM"
38+
export SKIP_VALIDATE="true"
39+
export USE_CACHE="true"
40+
export FAST_BUILD="true"
41+
3842
echo "Starting docker build and push for version: $DOCKER_VERSION ($PLATFORM)"
3943

4044
# We use 'node common/scripts/install-run-rush.js' to ensure we use the right rush version

desktop/src/ui/platform.ts

Lines changed: 130 additions & 130 deletions
Large diffs are not rendered by default.

dev/prod/benchmarks.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# Webpack vs Rspack Benchmarks (Huly Monorepo)
2+
3+
This file tracks the performance metrics for the transition from Webpack to Rspack.
4+
5+
## 1. Full Builds & Initial Startup
6+
7+
| Metric | Webpack (Original) | Rspack (New) | Improvement |
8+
| :--- | :--- | :--- | :--- |
9+
| **Production Build** (`package` vs `rs:build`) | 2m 50s (170s) | **47s** | **~3.6x** |
10+
| **Dev Server Cold Start** | 1m 00s (60s) | **43s** | **~1.4x** |
11+
12+
> [!NOTE]
13+
> Cold start improvement is lower because Rspack is now correctly bundling **all** dynamic resources upfront to prevent the "refresh waterfall."
14+
15+
## 2. Hot Module Replacement (HMR)
16+
17+
| Metric | Webpack | Rspack | Improvement |
18+
| :--- | :--- | :--- | :--- |
19+
| **Single Component Recompile** | 16.2s | **0.8s** | **~20x** |
20+
21+
---
22+
*Last updated: 2026-03-01*

dev/prod/package.json

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,19 +6,19 @@
66
"scripts": {
77
"_phase:package": "rushx package",
88
"_phase:validate": "rm -rf ./types && compile validate",
9-
"package": "rm -rf ./dist && cross-env NODE_ENV=production webpack --stats-error-details && echo 'done'",
10-
"analyze": "rm -rf ./dist && cross-env NODE_ENV=production webpack --profile --json > stats.json",
9+
"package": "rm -rf ./dist && cross-env NODE_ENV=production rspack build --config rspack.config.ts && echo 'done'",
10+
"analyze": "rm -rf ./dist && cross-env NODE_ENV=production rspack build --config rspack.config.ts --profile --json > stats.json",
1111
"show": "webpack-bundle-analyzer stats.json dist",
12-
"dev-server": "cross-env USE_CACHE=false CLIENT_TYPE=dev-server webpack serve",
13-
"dev-server-test": "cross-env USE_CACHE=false CLIENT_TYPE=dev-server-test webpack serve",
14-
"dev-worker": "cross-env USE_CACHE=false CLIENT_TYPE=dev-worker webpack serve",
15-
"dev-worker-local": "cross-env USE_CACHE=false CLIENT_TYPE=dev-worker-local webpack serve",
16-
"dev-server-cache": "cross-env USE_CACHE=true CLIENT_TYPE=dev-server webpack serve",
12+
"dev-server": "cross-env USE_CACHE=false CLIENT_TYPE=dev-server rspack serve --config rspack.config.ts",
13+
"dev-server-test": "cross-env USE_CACHE=false CLIENT_TYPE=dev-server-test rspack serve --config rspack.config.ts",
14+
"dev-worker": "cross-env USE_CACHE=false CLIENT_TYPE=dev-worker rspack serve --config rspack.config.ts",
15+
"dev-worker-local": "cross-env USE_CACHE=false CLIENT_TYPE=dev-worker-local rspack serve --config rspack.config.ts",
16+
"dev-server-cache": "cross-env USE_CACHE=true CLIENT_TYPE=dev-server rspack serve --config rspack.config.ts",
1717
"tunnel-qms": "socat tcp-listen:8081,reuseaddr,fork,bind=localhost tcp:localhost:8080",
18-
"dev-production": "cross-env CLIENT_TYPE=dev-production webpack serve",
19-
"dev-huly": "cross-env CLIENT_TYPE=dev-huly webpack serve",
20-
"dev-bold": "cross-env CLIENT_TYPE=dev-bold webpack serve",
21-
"start": "cross-env NODE_ENV=production webpack serve",
18+
"dev-production": "cross-env CLIENT_TYPE=dev-production rspack serve --config rspack.config.ts",
19+
"dev-huly": "cross-env CLIENT_TYPE=dev-huly rspack serve --config rspack.config.ts",
20+
"dev-bold": "cross-env CLIENT_TYPE=dev-bold rspack serve --config rspack.config.ts",
21+
"start": "cross-env NODE_ENV=production rspack serve --config rspack.config.ts",
2222
"deploy": "cp -p public/* dist && aws s3 sync dist s3://anticrm-platform --delete --acl public-read",
2323
"format": "echo 'no format yet'"
2424
},
@@ -52,7 +52,10 @@
5252
"webpack": "^5.97.1",
5353
"webpack-bundle-analyzer": "^4.10.2",
5454
"webpack-cli": "^5.1.4",
55-
"webpack-dev-server": "^4.11.1"
55+
"webpack-dev-server": "^4.11.1",
56+
"@rspack/core": "^1.2.0",
57+
"@rspack/cli": "^1.2.0",
58+
"tsconfig-paths-webpack-plugin": "^4.1.0"
5659
},
5760
"dependencies": {
5861
"@hcengineering/achievement": "workspace:^0.7.0",

dev/prod/rspack.config.ts

Lines changed: 208 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,208 @@
1+
import { defineConfig } from '@rspack/cli';
2+
import { rspack } from '@rspack/core';
3+
import path from 'path';
4+
5+
const mode = process.env.NODE_ENV || 'development';
6+
const prod = mode === 'production';
7+
8+
const clientType = process.env.CLIENT_TYPE || '';
9+
const dev = mode === 'development' || clientType === 'dev';
10+
11+
const devProxy = [
12+
{
13+
context: ['/account'],
14+
target: 'http://huly.local:3000',
15+
changeOrigin: true,
16+
pathRewrite: { '^/account': '' },
17+
},
18+
{
19+
context: ['/api/v1', '/files', '/import'],
20+
target: 'http://huly.local:8087',
21+
changeOrigin: true,
22+
},
23+
{
24+
context: ['/rekoni/recognize'],
25+
target: 'http://huly.local:4004',
26+
changeOrigin: true,
27+
pathRewrite: { '^/rekoni/recognize': '/recognize' },
28+
}
29+
];
30+
31+
const devProxyTest = [
32+
{
33+
context: ['/account'],
34+
target: 'http://huly.local:3003',
35+
changeOrigin: true,
36+
pathRewrite: { '^/account': '' },
37+
},
38+
{
39+
context: ['/api/v1', '/files', '/import'],
40+
target: 'http://huly.local:8083',
41+
changeOrigin: true,
42+
},
43+
{
44+
context: ['/rekoni/recognize'],
45+
target: 'http://huly.local:4004',
46+
changeOrigin: true,
47+
pathRewrite: { '^/rekoni/recognize': '/recognize' },
48+
}
49+
];
50+
51+
const proxies: Record<string, any> = {
52+
'dev-worker': devProxy,
53+
'dev-worker-local': devProxy,
54+
'dev-server': devProxy,
55+
'dev-server-test': devProxyTest,
56+
};
57+
58+
export default defineConfig({
59+
mode: prod ? 'production' : 'development',
60+
context: __dirname,
61+
entry: {
62+
main: [
63+
'@hcengineering/theme/styles/global.scss',
64+
'./src/eager-bundle.ts',
65+
dev && (clientType === 'dev-server' || clientType === 'dev') ? './src/main-dev.ts' : './src/main.ts'
66+
],
67+
},
68+
output: {
69+
path: path.resolve(__dirname, 'dist'),
70+
filename: '[name].[contenthash].js',
71+
publicPath: '/',
72+
clean: true,
73+
},
74+
resolve: {
75+
extensions: ['.mjs', '.js', '.svelte', '.ts'],
76+
mainFields: ['svelte', 'browser', 'module', 'main'],
77+
conditionNames: ['svelte', 'browser', 'import'],
78+
alias: {
79+
'@hcengineering/platform-rig/profiles/ui/svelte$': path.resolve(__dirname, 'node_modules/svelte/src/runtime/index.js'),
80+
},
81+
fallback: {
82+
crypto: false,
83+
fs: false,
84+
path: false,
85+
os: false,
86+
net: false,
87+
tls: false,
88+
child_process: false,
89+
http: false,
90+
https: false,
91+
stream: false,
92+
constants: false,
93+
dns: false,
94+
},
95+
symlinks: true,
96+
},
97+
module: {
98+
rules: [
99+
{
100+
test: /\.svelte$/,
101+
use: [
102+
{
103+
loader: 'svelte-loader',
104+
options: {
105+
preprocess: require('svelte-preprocess')({
106+
postcss: true,
107+
scss: {
108+
silenceDeprecations: ['legacy-js-api']
109+
}
110+
}),
111+
onwarn: (warning: any, handler: any) => {
112+
if (warning.code === 'css-unused-selector' || warning.code === 'a11y-missing-attribute') return;
113+
handler(warning);
114+
}
115+
},
116+
},
117+
],
118+
},
119+
{
120+
test: /\.ts$/,
121+
exclude: [/node_modules/],
122+
loader: 'builtin:swc-loader',
123+
options: {
124+
jsc: {
125+
parser: {
126+
syntax: 'typescript',
127+
},
128+
preserveAllComments: true,
129+
},
130+
},
131+
type: 'javascript/auto',
132+
},
133+
{
134+
test: /\.scss$/,
135+
use: [
136+
'style-loader',
137+
'css-loader',
138+
{
139+
loader: 'sass-loader',
140+
options: {
141+
api: 'modern',
142+
sassOptions: {
143+
quietDeps: true,
144+
},
145+
},
146+
},
147+
],
148+
type: 'javascript/auto',
149+
},
150+
{
151+
test: /\.css$/,
152+
use: [
153+
'style-loader',
154+
'css-loader',
155+
],
156+
type: 'javascript/auto',
157+
},
158+
{
159+
test: /\.(png|svg|jpg|webp|avif|ico|wav|mp3|ogg|aac|woff|woff2|ttf|otf)$/,
160+
type: 'asset/resource',
161+
},
162+
],
163+
},
164+
optimization: {
165+
splitChunks: false,
166+
},
167+
lazyCompilation: false,
168+
stats: 'errors-only',
169+
infrastructureLogging: {
170+
level: 'none',
171+
},
172+
plugins: [
173+
new rspack.HtmlRspackPlugin({
174+
meta: {
175+
viewport: 'width=device-width, initial-scale=1.0',
176+
},
177+
}),
178+
new rspack.DefinePlugin({
179+
'process.env.NODE_ENV': JSON.stringify(mode),
180+
'process.env.CLIENT_TYPE': JSON.stringify(clientType),
181+
}),
182+
],
183+
devServer: {
184+
port: 8080,
185+
host: '0.0.0.0',
186+
allowedHosts: 'all',
187+
historyApiFallback: {
188+
disableDotRule: true,
189+
},
190+
devMiddleware: {
191+
publicPath: '/',
192+
},
193+
client: {
194+
overlay: false,
195+
logging: 'none',
196+
},
197+
proxy: proxies[clientType] || devProxy,
198+
static: {
199+
directory: path.resolve(__dirname, 'public'),
200+
publicPath: '/',
201+
},
202+
hot: true,
203+
},
204+
watchOptions: {
205+
ignored: /node_modules/,
206+
poll: 1000,
207+
},
208+
});

0 commit comments

Comments
 (0)