Skip to content

Commit

Permalink
feat(client): Upgrade to Node 20, Webpack 5, Blueprint 5
Browse files Browse the repository at this point in the history
  • Loading branch information
fushar committed Dec 27, 2023
1 parent ebde3c0 commit 18cd439
Show file tree
Hide file tree
Showing 50 changed files with 6,437 additions and 8,813 deletions.
1 change: 1 addition & 0 deletions judgels-client/config/paths.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ module.exports = {
testsSetup: resolveModule(resolveApp, 'src/setupTests'),
proxySetup: resolveApp('src/setupProxy.js'),
appNodeModules: resolveApp('node_modules'),
appWebpackCache: resolveApp('node_modules/.cache'),
swSrc: resolveModule(resolveApp, 'src/service-worker'),
publicUrlOrPath,
};
Expand Down
263 changes: 116 additions & 147 deletions judgels-client/config/webpack.config.js

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@

const { createHash } = require('crypto');

module.exports = env => {
const hash = createHash('md5');
hash.update(JSON.stringify(env));

return hash.digest('hex');
};
135 changes: 66 additions & 69 deletions judgels-client/config/webpackDevServer.config.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
'use strict';


const fs = require('fs');
const errorOverlayMiddleware = require('react-dev-utils/errorOverlayMiddleware');
const evalSourceMapMiddleware = require('react-dev-utils/evalSourceMapMiddleware');
const noopServiceWorkerMiddleware = require('react-dev-utils/noopServiceWorkerMiddleware');
const ignoredFiles = require('react-dev-utils/ignoredFiles');
Expand All @@ -11,10 +10,12 @@ const getHttpsConfig = require('./getHttpsConfig');

const host = process.env.HOST || '0.0.0.0';
const sockHost = process.env.WDS_SOCKET_HOST;
const sockPath = process.env.WDS_SOCKET_PATH; // default: '/sockjs-node'
const sockPath = process.env.WDS_SOCKET_PATH; // default: '/ws'
const sockPort = process.env.WDS_SOCKET_PORT;

module.exports = function (proxy, allowedHost) {
const disableFirewall =
!proxy || process.env.DANGEROUSLY_DISABLE_HOST_CHECK === 'true';
return {
// WebpackDevServer 2.4.3 introduced a security fix that prevents remote
// websites from potentially accessing local content through DNS rebinding:
Expand All @@ -32,99 +33,95 @@ module.exports = function (proxy, allowedHost) {
// So we will disable the host check normally, but enable it if you have
// specified the `proxy` setting. Finally, we let you override it if you
// really know what you're doing with a special environment variable.
disableHostCheck:
!proxy || process.env.DANGEROUSLY_DISABLE_HOST_CHECK === 'true',
// Note: ["localhost", ".localhost"] will support subdomains - but we might
// want to allow setting the allowedHosts manually for more complex setups
allowedHosts: disableFirewall ? 'all' : [allowedHost],
headers: {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': '*',
'Access-Control-Allow-Headers': '*',
},
// Enable gzip compression of generated files.
compress: true,
// Silence WebpackDevServer's own logs since they're generally not useful.
// It will still show compile warnings and errors with this setting.
clientLogLevel: 'none',
// By default WebpackDevServer serves physical files from current directory
// in addition to all the virtual build products that it serves from memory.
// This is confusing because those files won’t automatically be available in
// production build folder unless we copy them. However, copying the whole
// project directory is dangerous because we may expose sensitive files.
// Instead, we establish a convention that only files in `public` directory
// get served. Our build script will copy `public` into the `build` folder.
// In `index.html`, you can get URL of `public` folder with %PUBLIC_URL%:
// <link rel="icon" href="%PUBLIC_URL%/favicon.ico">
// In JavaScript code, you can access it with `process.env.PUBLIC_URL`.
// Note that we only recommend to use `public` folder as an escape hatch
// for files like `favicon.ico`, `manifest.json`, and libraries that are
// for some reason broken when imported through webpack. If you just want to
// use an image, put it in `src` and `import` it from JavaScript instead.
contentBase: paths.appPublic,
contentBasePublicPath: paths.publicUrlOrPath,
// By default files from `contentBase` will not trigger a page reload.
watchContentBase: true,
// Enable hot reloading server. It will provide WDS_SOCKET_PATH endpoint
// for the WebpackDevServer client so it can learn when the files were
// updated. The WebpackDevServer client is included as an entry point
// in the webpack development configuration. Note that only changes
// to CSS are currently hot reloaded. JS changes will refresh the browser.
hot: true,
// Use 'ws' instead of 'sockjs-node' on server since we're using native
// websockets in `webpackHotDevClient`.
transportMode: 'ws',
// Prevent a WS client from getting injected as we're already including
// `webpackHotDevClient`.
injectClient: false,
// Enable custom sockjs pathname for websocket connection to hot reloading server.
// Enable custom sockjs hostname, pathname and port for websocket connection
// to hot reloading server.
sockHost,
sockPath,
sockPort,
// It is important to tell WebpackDevServer to use the same "publicPath" path as
// we specified in the webpack config. When homepage is '.', default to serving
// from the root.
// remove last slash so user can land on `/test` instead of `/test/`
publicPath: paths.publicUrlOrPath.slice(0, -1),
// WebpackDevServer is noisy by default so we emit custom message instead
// by listening to the compiler events with `compiler.hooks[...].tap` calls above.
quiet: true,
// Reportedly, this avoids CPU overload on some systems.
// https://github.com/facebook/create-react-app/issues/293
// src/node_modules is not ignored to support absolute imports
// https://github.com/facebook/create-react-app/issues/1065
watchOptions: {
ignored: ignoredFiles(paths.appSrc),
static: {
// By default WebpackDevServer serves physical files from current directory
// in addition to all the virtual build products that it serves from memory.
// This is confusing because those files won’t automatically be available in
// production build folder unless we copy them. However, copying the whole
// project directory is dangerous because we may expose sensitive files.
// Instead, we establish a convention that only files in `public` directory
// get served. Our build script will copy `public` into the `build` folder.
// In `index.html`, you can get URL of `public` folder with %PUBLIC_URL%:
// <link rel="icon" href="%PUBLIC_URL%/favicon.ico">
// In JavaScript code, you can access it with `process.env.PUBLIC_URL`.
// Note that we only recommend to use `public` folder as an escape hatch
// for files like `favicon.ico`, `manifest.json`, and libraries that are
// for some reason broken when imported through webpack. If you just want to
// use an image, put it in `src` and `import` it from JavaScript instead.
directory: paths.appPublic,
publicPath: [paths.publicUrlOrPath],
// By default files from `contentBase` will not trigger a page reload.
watch: {
// Reportedly, this avoids CPU overload on some systems.
// https://github.com/facebook/create-react-app/issues/293
// src/node_modules is not ignored to support absolute imports
// https://github.com/facebook/create-react-app/issues/1065
ignored: ignoredFiles(paths.appSrc),
},
},
client: {
webSocketURL: {
// Enable custom sockjs pathname for websocket connection to hot reloading server.
// Enable custom sockjs hostname, pathname and port for websocket connection
// to hot reloading server.
hostname: sockHost,
pathname: sockPath,
port: sockPort,
},
overlay: {
errors: true,
warnings: false,
},
},
devMiddleware: {
// It is important to tell WebpackDevServer to use the same "publicPath" path as
// we specified in the webpack config. When homepage is '.', default to serving
// from the root.
// remove last slash so user can land on `/test` instead of `/test/`
publicPath: paths.publicUrlOrPath.slice(0, -1),
},

https: getHttpsConfig(),
host,
overlay: false,
historyApiFallback: {
// Paths with dots should still use the history fallback.
// See https://github.com/facebook/create-react-app/issues/387.
disableDotRule: true,
index: paths.publicUrlOrPath,
},
public: allowedHost,
// `proxy` is run between `before` and `after` `webpack-dev-server` hooks
proxy,
before(app, server) {
// Keep `evalSourceMapMiddleware` and `errorOverlayMiddleware`
onBeforeSetupMiddleware(devServer) {
// Keep `evalSourceMapMiddleware`
// middlewares before `redirectServedPath` otherwise will not have any effect
// This lets us fetch source contents from webpack for the error overlay
app.use(evalSourceMapMiddleware(server));
// This lets us open files from the runtime error overlay.
app.use(errorOverlayMiddleware());
devServer.app.use(evalSourceMapMiddleware(devServer));

if (fs.existsSync(paths.proxySetup)) {
// This registers user provided middleware for proxy reasons
require(paths.proxySetup)(app);
require(paths.proxySetup)(devServer.app);
}
},
after(app) {
onAfterSetupMiddleware(devServer) {
// Redirect to `PUBLIC_URL` or `homepage` from `package.json` if url not match
app.use(redirectServedPath(paths.publicUrlOrPath));
devServer.app.use(redirectServedPath(paths.publicUrlOrPath));

// This service worker file is effectively a 'no-op' that will reset any
// previous service worker registered for the same host:port combination.
// We do this in development to avoid hitting the production cache if
// it used the same host and port.
// https://github.com/facebook/create-react-app/issues/2272#issuecomment-302832432
app.use(noopServiceWorkerMiddleware(paths.publicUrlOrPath));
devServer.app.use(noopServiceWorkerMiddleware(paths.publicUrlOrPath));
},
};
};
49 changes: 25 additions & 24 deletions judgels-client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,25 @@
"private": true,
"dependencies": {
"@babel/core": "7.12.3",
"@blueprintjs/core": "4.0.0-alpha.0",
"@blueprintjs/datetime": "4.0.0-alpha.0",
"@blueprintjs/icons": "4.0.0-alpha.0",
"@blueprintjs/select": "4.0.0-alpha.0",
"@blueprintjs/core": "5.7.2",
"@blueprintjs/datetime": "5.2.8",
"@blueprintjs/icons": "5.5.0",
"@blueprintjs/select": "5.0.20",
"@react-oauth/google": "^0.11.1",
"@svgr/webpack": "5.5.0",
"@svgr/webpack": "8.1.0",
"ace-builds": "^1.26.0",
"babel-eslint": "^10.1.0",
"babel-jest": "^26.6.0",
"babel-loader": "8.1.0",
"babel-loader": "9.1.3",
"babel-plugin-named-asset-import": "^0.3.7",
"babel-preset-react-app": "^10.0.0",
"babel-preset-react-app": "10.0.1",
"bfj": "^7.0.2",
"camelcase": "^6.1.0",
"case-sensitive-paths-webpack-plugin": "2.3.0",
"classnames": "^2.2.5",
"connected-react-router": "6.9.1",
"css-loader": "4.3.0",
"css-loader": "6.8.1",
"css-minimizer-webpack-plugin": "5.0.1",
"dotenv": "8.2.0",
"dotenv-expand": "5.1.0",
"eslint": "^7.11.0",
Expand All @@ -38,7 +39,7 @@
"fs-extra": "^9.0.1",
"history": "4.9.0",
"html-react-parser": "1.2.6",
"html-webpack-plugin": "4.5.0",
"html-webpack-plugin": "5.5.4",
"identity-obj-proxy": "3.0.0",
"jest": "26.6.0",
"jest-circus": "26.6.0",
Expand All @@ -47,22 +48,21 @@
"katex": "0.13.11",
"mini-css-extract-plugin": "0.11.3",
"normalize.css": "^5.0.0",
"optimize-css-assets-webpack-plugin": "5.0.4",
"pnp-webpack-plugin": "1.6.4",
"postcss": "8.4.32",
"postcss-flexbugs-fixes": "4.2.1",
"postcss-loader": "3.0.0",
"postcss-normalize": "8.0.1",
"postcss-preset-env": "6.7.0",
"postcss-safe-parser": "5.0.2",
"preact": "10.5.13",
"postcss-loader": "7.3.3",
"postcss-normalize": "10.0.1",
"postcss-preset-env": "9.3.0",
"postcss-safe-parser": "7.0.0",
"preact": "10.19.3",
"preact-render-to-string": "5.1.19",
"pretty-bytes": "4.0.2",
"prompts": "2.4.0",
"query-string": "^5.1.0",
"react-ace": "^10.1.0",
"react-app-polyfill": "^2.0.0",
"react-async-script": "^0.9.1",
"react-dev-utils": "^11.0.3",
"react-dev-utils": "12.0.1",
"react-document-title": "2.0.3",
"react-final-form": "^6.5.3",
"react-ga4": "2.1.0",
Expand All @@ -79,17 +79,17 @@
"reset-css": "^2.2.0",
"resolve-url-loader": "^3.1.2",
"sass": "1.34.0",
"sass-loader": "^10.0.5",
"style-loader": "1.3.0",
"terser-webpack-plugin": "4.2.3",
"sass-loader": "13.3.2",
"style-loader": "3.3.3",
"terser-webpack-plugin": "5.3.9",
"tinymce": "^4.9.11",
"typeface-open-sans": "^0.0.54",
"typeface-roboto": "^0.0.54",
"url-loader": "4.1.1",
"webpack": "4.44.2",
"webpack-dev-server": "3.11.1",
"webpack-manifest-plugin": "2.2.0",
"workbox-webpack-plugin": "5.1.4"
"webpack": "5.89.0",
"webpack-dev-server": "4.15.1",
"webpack-manifest-plugin": "5.0.0",
"workbox-webpack-plugin": "7.0.0"
},
"scripts": {
"ci": "npm-run-all lint test",
Expand All @@ -100,6 +100,7 @@
"test": "TZ=Asia/Jakarta node scripts/test.js"
},
"devDependencies": {
"@babel/plugin-transform-private-property-in-object": "7.23.4",
"enzyme": "^3.2.0",
"enzyme-adapter-preact-pure": "^3.1.0",
"nock": "11.7.2",
Expand Down
5 changes: 5 additions & 0 deletions judgels-client/src/components/Card/Card.scss
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,8 @@
margin-bottom: 10px;
overflow-x: auto;
}

.bp5-dark .bp5-card {
background-color: #30404d;
box-shadow: 0 0 0 1px rgba(16,22,26,.4), 0 0 0 rgba(16,22,26,0), 0 0 0 rgba(16,22,26,0);
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,6 @@

button {
float: right;
margin-left: 5px;
}
}
4 changes: 2 additions & 2 deletions judgels-client/src/components/ContentCard/ContentCard.scss
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
}
}

.bp4-dark .content-card {
.bp5-dark .content-card {
box-shadow: 0 0 0 0.5px $gray1 !important;
}

Expand All @@ -26,7 +26,7 @@
margin-bottom: 5px;
}

.bp4-form-group {
.bp5-form-group {
margin-bottom: 0;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import './ContentCardLink.scss';
export function ContentCardLink({ className, to, elevation, children }) {
// This is basically a <ContentCard /> but with div replaced with a.
return (
<Link className={`bp4-card bp-elevation-${elevation} content-card content-card-link`} to={to}>
<Link className={`bp5-card bp-elevation-${elevation} content-card content-card-link`} to={to}>
<div className={classNames('content-card-link__content', className)}>{children}</div>
</Link>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@
text-decoration: none;
}

.bp4-light .content-card-link:hover {
.bp5-light .content-card-link:hover {
background-color: $secondary-background-color;
}

.bp4-dark .content-card-link:hover {
.bp5-dark .content-card-link:hover {
background-color: $dark-secondary-background-color;
}

Expand Down
Loading

0 comments on commit 18cd439

Please sign in to comment.