Skip to content

Commit e096e02

Browse files
committed
feat! replace webpack by rsbuild for faster build
TODO: - Remove regisb/rsbuild hardcoded forks
1 parent 856ea2a commit e096e02

File tree

3 files changed

+179
-6
lines changed

3 files changed

+179
-6
lines changed

tutormfe/plugin.py

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
}
3333

3434
CORE_MFE_APPS: dict[str, MFE_ATTRS_TYPE] = {
35+
# TODO restore vanilla repositories
3536
"authn": {
3637
"repository": "https://github.com/openedx/frontend-app-authn.git",
3738
"port": 1999,
@@ -45,27 +46,35 @@
4546
"port": 1997,
4647
},
4748
"communications": {
48-
"repository": "https://github.com/openedx/frontend-app-communications.git",
49+
"repository": "https://github.com/regisb/frontend-app-communications.git",
50+
"version": "regisb/rsbuild",
51+
# "repository": "https://github.com/openedx/frontend-app-communications.git",
4952
"port": 1984,
5053
},
5154
"discussions": {
5255
"repository": "https://github.com/openedx/frontend-app-discussions.git",
5356
"port": 2002,
5457
},
5558
"gradebook": {
56-
"repository": "https://github.com/openedx/frontend-app-gradebook.git",
59+
"repository": "https://github.com/regisb/frontend-app-gradebook.git",
60+
"version": "regisb/rsbuild",
61+
# "repository": "https://github.com/openedx/frontend-app-gradebook.git",
5762
"port": 1994,
5863
},
5964
"learner-dashboard": {
60-
"repository": "https://github.com/openedx/frontend-app-learner-dashboard.git",
65+
"repository": "https://github.com/regisb/frontend-app-learner-dashboard.git",
66+
"version": "regisb/rsbuild",
67+
# "repository": "https://github.com/openedx/frontend-app-learner-dashboard.git",
6168
"port": 1996,
6269
},
6370
"learning": {
6471
"repository": "https://github.com/openedx/frontend-app-learning.git",
6572
"port": 2000,
6673
},
6774
"ora-grading": {
68-
"repository": "https://github.com/openedx/frontend-app-ora-grading.git",
75+
"repository": "https://github.com/regisb/frontend-app-ora-grading.git",
76+
"version": "regisb/rsbuild",
77+
# "repository": "https://github.com/openedx/frontend-app-ora-grading.git",
6978
"port": 1993,
7079
},
7180
"profile": {

tutormfe/templates/mfe/build/mfe/Dockerfile

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,14 @@ RUN apt update \
1717
libcairo2-dev libpango1.0-dev libjpeg-dev libgif-dev librsvg2-dev
1818

1919
RUN mkdir -p /openedx/app /openedx/env
20+
21+
# Install shared dependencies in /openedx/node_modules
22+
WORKDIR /openedx/
23+
RUN npm install @rsbuild/core @rsbuild/plugin-react @rsbuild/plugin-svgr @rsbuild/plugin-sass
24+
25+
# Install apps in /openedx/app
2026
WORKDIR /openedx/app
21-
ENV PATH=/openedx/app/node_modules/.bin:${PATH}
27+
ENV PATH=/openedx/app/node_modules/.bin:/openedx/node_modules/.bin:${PATH}
2228

2329
{{ patch("mfe-dockerfile-base") }}
2430

@@ -77,7 +83,8 @@ CMD ["/bin/bash", "-c", "npm run start --- --config ./webpack.dev-tutor.config.j
7783
######## {{ app_name }} (production)
7884
FROM {{ app_name }}-common AS {{ app_name }}-prod
7985
ENV NODE_ENV=production
80-
RUN npm run build
86+
COPY rsbuild.config.ts /openedx/app/rsbuild.config.ts
87+
RUN rsbuild build
8188
{{ patch("mfe-dockerfile-post-npm-build") }}
8289
{{ patch("mfe-dockerfile-post-npm-build-{}".format(app_name)) }}
8390
{% endfor %}
Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
// Install dependencies:
2+
//
3+
// npm install --no-save @rsbuild/core @rsbuild/plugin-react @rsbuild/plugin-svgr @rsbuild/plugin-sass @rsdoctor/rspack-plugin
4+
//
5+
// Build with:
6+
//
7+
// rsbuild build
8+
//
9+
// Develop with:
10+
//
11+
// rsbuild
12+
//
13+
// Troubleshoot with:
14+
//
15+
// RSDOCTOR=true rsbuild build
16+
17+
import path from 'path';
18+
import fs from 'fs';
19+
import { defineConfig } from '@rsbuild/core';
20+
import { pluginReact } from '@rsbuild/plugin-react';
21+
import { pluginSvgr } from '@rsbuild/plugin-svgr';
22+
import { pluginSass } from '@rsbuild/plugin-sass';
23+
import { loadEnv } from '@rsbuild/core';
24+
25+
// Load environment variables
26+
// https://rsbuild.dev/api/javascript-api/core#loadenv
27+
const currentDir = process.cwd();
28+
const parsedEnv = loadEnv({ mode: 'production' }).parsed;
29+
const parsedEnvDev = loadEnv({ mode: 'development' }).parsed;
30+
const appName = parsedEnv.APP_ID || path.basename(currentDir).replace('frontend-app-', '');
31+
const publicPath = parsedEnv.PUBLIC_PATH || '/' + appName + '/';
32+
const dev = parsedEnv.NODE_ENV === 'development';
33+
const prod = !dev;
34+
parsedEnv.APP_ID = appName;
35+
parsedEnv.PUBLIC_PATH = publicPath;
36+
parsedEnv.MFE_CONFIG_API_URL = prod ? '/api/mfe_config/v1' : 'http://local.openedx.io:8000/api/mfe_config/v1';
37+
38+
// Load env.config.(js|jsx)
39+
var envConfigPath = '';
40+
try {
41+
await import('@openedx/frontend-plugin-framework');
42+
if (fs.existsSync(path.resolve(currentDir, './env.config.jsx'))) {
43+
envConfigPath = path.resolve(currentDir, './env.config.jsx');
44+
} else if (fs.existsSync(path.resolve(currentDir, './env.config.js'))) {
45+
envConfigPath = path.resolve(currentDir, './env.config.js');
46+
}
47+
} catch {
48+
// FPF is not available, we don't try to load env.config.js
49+
}
50+
51+
const config = defineConfig({
52+
html: {
53+
template: './public/index.html',
54+
},
55+
output: {
56+
// Flat directory
57+
// TODO do we want a flat directory?
58+
// distPath: {
59+
// js: '',
60+
// css: '',
61+
// },
62+
sourceMap: {
63+
js: prod ? 'source-map' : 'eval',
64+
css: true,
65+
}
66+
},
67+
performance: {
68+
// We enable caching everywhere, even if it's unnecessary in some places. The
69+
// negative impact on performance should be minor.
70+
buildCache: true,
71+
},
72+
server: {
73+
base: publicPath,
74+
// Redirect all get requests to index.html
75+
// https://rsbuild.dev/config/server/history-api-fallback
76+
historyApiFallback: true,
77+
port: parseInt(parsedEnvDev.PORT),
78+
},
79+
source: {
80+
define: {
81+
// This is explicitly recommended against, but this is how MFEs are built
82+
// https://rsbuild.dev/guide/advanced/env-vars#processenv-replacement
83+
'process.env': JSON.stringify(parsedEnv),
84+
},
85+
transformImport: [
86+
// https://rsbuild.dev/config/source/transform-import#import-lodash-on-demand
87+
{
88+
libraryName: 'lodash',
89+
customName: 'lodash/{' + '{ member }' + '}',
90+
},
91+
{
92+
libraryName: '@fortawesome/free-brands-svg-icons',
93+
customName: '@fortawesome/free-brands-svg-icons/{' + '{ member }' + '}',
94+
transformToDefaultImport: false,
95+
},
96+
{
97+
libraryName: '@fortawesome/free-regular-svg-icons',
98+
customName: '@fortawesome/free-regular-svg-icons/{' + '{ member }' + '}',
99+
transformToDefaultImport: false,
100+
},
101+
{
102+
libraryName: '@fortawesome/free-solid-svg-icons',
103+
customName: '@fortawesome/free-solid-svg-icons/{' + '{ member }' + '}',
104+
transformToDefaultImport: false,
105+
},
106+
],
107+
},
108+
plugins: [
109+
// https://rsbuild.dev/plugins/list/plugin-react
110+
pluginReact(),
111+
// https://rsbuild.dev/plugins/list/plugin-svgr#mixedimport
112+
pluginSvgr({
113+
mixedImport: true,
114+
svgrOptions: {
115+
exportType: 'named',
116+
},
117+
}),
118+
// https://rsbuild.dev/plugins/list/plugin-sass
119+
pluginSass({
120+
sassLoaderOptions: {
121+
sassOptions: {
122+
silenceDeprecations: ['abs-percent', 'color-functions', 'import', 'mixed-decls', 'global-builtin', 'legacy-js-api'],
123+
},
124+
},
125+
}),
126+
],
127+
resolve: {
128+
alias: {
129+
'env.config': envConfigPath || false,
130+
}
131+
}
132+
});
133+
134+
///////////////////////
135+
// MFE-specific changes
136+
///////////////////////
137+
138+
// This is horrible but we don't have a choice
139+
if (appName == 'authoring') {
140+
config.resolve!.alias!['CourseAuthoring'] = path.resolve(currentDir, 'src/');
141+
} else if (appName == 'communications') {
142+
// config.resolve!.alias![''] = './src';
143+
config.resolve!.alias!['@src'] = path.resolve(currentDir, 'src');
144+
} else if (appName == 'gradebook') {
145+
// config.resolve!.alias![''] = './src';
146+
config.resolve!.alias!['@src'] = path.resolve(currentDir, 'src');
147+
} else if (appName == 'learner-dashboard') {
148+
// config.resolve!.alias![''] = './src';
149+
config.resolve!.alias!['@src'] = path.resolve(currentDir, 'src');
150+
} else if (appName === 'learning') {
151+
config.resolve!.alias!['@src'] = path.resolve(currentDir, 'src');
152+
} else if (appName == 'ora-grading') {
153+
// config.resolve!.alias![''] = './src';
154+
config.resolve!.alias!['@src'] = path.resolve(currentDir, 'src');
155+
}
156+
157+
export default config;

0 commit comments

Comments
 (0)