Skip to content

Commit

Permalink
Merge pull request #51 from ogarich89/feature/rspack
Browse files Browse the repository at this point in the history
Migrate webpack to rspack
  • Loading branch information
ogarich89 authored Oct 27, 2024
2 parents 762107d + 63136c8 commit c68ebba
Show file tree
Hide file tree
Showing 9 changed files with 1,294 additions and 529 deletions.
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ ISO uses a number of open source projects to work properly:
* [Fastify](https://www.fastify.io/) - Fast and low overhead web framework, for Node.js
* [React](https://reactjs.org/) - JavaScript library for building user interfaces
* [Redux](https://redux.js.org/) - A Predictable State Container for JS Apps
* [Webpack](https://webpack.js.org/) - Module bundler
* [HMR](https://webpack.js.org/concepts/hot-module-replacement/) - Hot Module Replacement
* [Rspack](https://rspack.dev/) - Module bundler
* [HMR](https://rspack.dev/api/runtime-api/hmr) - Hot Module Replacement
* [Browsersync](https://browsersync.io/) - Time-saving synchronised browser testing
* [SWC](https://swc.rs/) - Rust-based platform for the Web
* [ESLint](https://eslint.org/) - Statically analyzes your code to quickly find problems.
Expand Down Expand Up @@ -69,7 +69,7 @@ $ touch config/environment/development.json
`withRedis` - Session with Redis store \
`inspect` - Debugging Node.js with Chrome DevTools \
`logger` - Fastify logger \
`analyze` - Webpack Bundle Analyzer \
`analyze` - Rsdoctor \
`sentryDSN` - Error monitoring with [Sentry](https://sentry.io) \
`certificate` - Optional object for run https server `{ "key": "/path/to/key.pem", "cert": "/path/to/cert.pem" }`

Expand Down Expand Up @@ -118,7 +118,7 @@ For production release:
```sh
$ yarn production
```
[Build mode](https://webpack.js.org/configuration/mode/) (development | production) depending on `NODE_ENV` \
[Build mode](https://rspack.dev/config/mode) (development | production) depending on `NODE_ENV` \
Reading file `config/environment/(staging | production).json` depending on `ENVIRONMENT`
```sh
$ yarn build
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import LoadablePlugin from '@loadable/webpack-plugin';
import MiniCssExtractPlugin from 'mini-css-extract-plugin';
import TerserPlugin from 'terser-webpack-plugin';
import webpack from 'webpack';
import { BundleAnalyzerPlugin } from 'webpack-bundle-analyzer';
import { RsdoctorRspackPlugin } from '@rsdoctor/rspack-plugin';
import rspack from '@rspack/core';
import { merge } from 'webpack-merge';

import { dirname, resolve } from 'path';
Expand All @@ -16,12 +14,16 @@ const __dirname = dirname(fileURLToPath(import.meta.url));

const { analyze, withStatic } = config;
const isDevelopment = process.env.NODE_ENV !== 'production';
const { default: ReactRefreshWebpackPlugin } = isDevelopment
? await import('@pmmmwh/react-refresh-webpack-plugin')
const { default: ReactRefreshPlugin } = isDevelopment
? await import('@rspack/plugin-react-refresh')
: { default: null };

export default merge(common(), {
context: resolve(__dirname, '../../src/root'),
performance: {
maxEntrypointSize: 500000,
maxAssetSize: 500000,
},
entry: {
bundle: [
'./client.tsx',
Expand All @@ -44,9 +46,8 @@ export default merge(common(), {
...(isDevelopment ? { runtimeChunk: 'single' } : {}),
minimize: !isDevelopment,
minimizer: [
new TerserPlugin({
minify: TerserPlugin.swcMinify,
terserOptions: {
new rspack.SwcJsMinimizerRspackPlugin({
minimizerOptions: {
compress: true,
format: {
comments: false,
Expand All @@ -55,50 +56,32 @@ export default merge(common(), {
extractComments: false,
}),
],
splitChunks: !isDevelopment
? {
cacheGroups: {
vendors: {
test: /[\\/]node_modules[\\/]/,
priority: -10,
reuseExistingChunk: true,
},
common: {
minChunks: 2,
priority: -20,
reuseExistingChunk: true,
},
},
chunks: 'all',
maxInitialRequests: 30,
maxAsyncRequests: 30,
maxSize: 250000,
}
: false,
},
plugins: [
...(analyze
? [
new BundleAnalyzerPlugin({
openAnalyzer: false,
analyzerMode: 'static',
}),
]
: []),
new MiniCssExtractPlugin({
new LoadablePlugin({ writeToDisk: true }),
new rspack.CssExtractRspackPlugin({
filename: isDevelopment
? 'css/[name].css'
: 'css/[name].[contenthash].css',
chunkFilename: isDevelopment
? 'css/[name].css'
: 'css/[name].[contenthash].css',
}),
new LoadablePlugin({ writeToDisk: true }),
...(isDevelopment
...(analyze
? [
new ReactRefreshWebpackPlugin(),
new webpack.HotModuleReplacementPlugin(),
new RsdoctorRspackPlugin({
disableClientServer: !isDevelopment,
mode: isDevelopment ? 'normal' : 'brief',
linter: {
rules: {
'ecma-version-check': 'off',
},
},
}),
]
: []),
...(isDevelopment
? [new ReactRefreshPlugin(), new rspack.HotModuleReplacementPlugin()]
: []),
],
});
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import MiniCssExtractPlugin from 'mini-css-extract-plugin';
import webpack from 'webpack';
import rspack from '@rspack/core';

import { dirname, resolve } from 'path';
import { fileURLToPath } from 'url';
Expand Down Expand Up @@ -32,12 +31,23 @@ const common = ({ isServer } = {}) => ({
{
test: /\.(ts|tsx|js|jsx)$/,
exclude: /node_modules/,
loader: 'swc-loader',
loader: 'builtin:swc-loader',
options: {
sourceMap: isDevelopment,
env: {
targets: {
chrome: '94',
safari: '15',
},
mode: 'usage',
coreJs: '3.36',
},
jsc: {
experimental: {
plugins: [['@swc/plugin-loadable-components', {}]],
plugins: [
['@swc/plugin-loadable-components', {}],
...(isDevelopment ? [['swc-plugin-add-display-name', {}]] : []),
],
},
parser: {
syntax: 'typescript',
Expand All @@ -58,7 +68,16 @@ const common = ({ isServer } = {}) => ({
{
test: /\.(scss|sass|css)$/,
use: [
...(!isServer ? [MiniCssExtractPlugin.loader] : []),
...(!isServer
? [
{
loader: rspack.CssExtractRspackPlugin.loader,
options: {
hmr: isDevelopment,
},
},
]
: []),
{
loader: 'css-loader',
options: {
Expand Down Expand Up @@ -92,6 +111,7 @@ const common = ({ isServer } = {}) => ({
},
},
],
type: 'javascript/auto',
},
{
test: /\.svg$/,
Expand All @@ -102,30 +122,27 @@ const common = ({ isServer } = {}) => ({
{
test: /\.(png|jpe?g|gif)$/i,
issuer: /\.(ts|tsx|js|jsx)$/,
use: [
{
loader: 'url-loader',
options: {
fallback: 'file-loader',
limit: 8192,
emitFile: !isServer,
name: isDevelopment ? '[name].[ext]' : '[name].[hash:8].[ext]',
outputPath: 'assets',
},
type: 'asset',
generator: {
emit: !isServer,
},
parser: {
dataUrlCondition: {
maxSize: 8 * 1024,
},
],
},
},
],
},
plugins: [
new webpack.DefinePlugin({
new rspack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify(
process.env.NODE_ENV || 'development',
),
isDevelopment,
timestamp: JSON.stringify(+new Date()),
}),
new webpack.LoaderOptionsPlugin({
new rspack.LoaderOptionsPlugin({
options: { failOnError: !isDevelopment },
}),
],
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import webpack from 'webpack';
import rspack from '@rspack/core';
import { merge } from 'webpack-merge';
import nodeExternals from 'webpack-node-externals';

Expand All @@ -21,11 +21,13 @@ export default merge(common({ isServer: true }), {
splitChunks: false,
},
output: {
library: {
type: 'commonjs-module',
},
path: resolve(__dirname, '../../dist'),
filename: 'request-handler.cjs',
libraryTarget: 'commonjs-static',
publicPath: '/',
},
externals: ['@loadable/component', nodeExternals()],
plugins: [new webpack.optimize.LimitChunkCountPlugin({ maxChunks: 1 })],
plugins: [new rspack.optimize.LimitChunkCountPlugin({ maxChunks: 1 })],
});
12 changes: 6 additions & 6 deletions gulpfile.mjs
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import { rspack } from '@rspack/core';
import browserSync from 'browser-sync';
import gulpNodemon from 'gulp-nodemon';
import webpack from 'webpack';
import webpackDevMiddleware from 'webpack-dev-middleware';
import webpackHotMiddleware from 'webpack-hot-middleware';

import { config } from './config/config.cjs';
import webpackClientConfig from './config/webpack/client.config.mjs';
import webpackServerConfig from './config/webpack/server.config.mjs';
import rspackClientConfig from './config/rspack/client.config.mjs';
import rspackServerConfig from './config/rspack/server.config.mjs';

const clientCompiler = webpack(webpackClientConfig);
const serverCompiler = webpack(webpackServerConfig);
const clientCompiler = rspack(rspackClientConfig);
const serverCompiler = rspack(rspackServerConfig);

const { inspect, port, browserSyncPort } = config;

Expand Down Expand Up @@ -40,7 +40,7 @@ export const server = () => {

export const client = () => {
const devMiddleware = webpackDevMiddleware(clientCompiler, {
publicPath: webpackClientConfig.output.publicPath,
publicPath: rspackClientConfig.output.publicPath,
});
browserSync.init(null, {
host: 'localhost',
Expand Down
22 changes: 9 additions & 13 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
"repository": "git@github.com:ogarich89/iso.git",
"type": "module",
"config": {
"server": "--config config/webpack/server.config.mjs",
"client": "--config config/webpack/client.config.mjs"
"server": "--config config/rspack/server.config.mjs",
"client": "--config config/rspack/client.config.mjs"
},
"engines": {
"node": "^20.*"
Expand All @@ -17,8 +17,8 @@
"server": "gulp server",
"nodemon": "gulp nodemon",
"dev": "gulp development",
"build": "webpack $npm_package_config_client && webpack $npm_package_config_server",
"production": "NODE_ENV=production webpack $npm_package_config_client && NODE_ENV=production webpack $npm_package_config_server",
"build": "rspack $npm_package_config_client && rspack $npm_package_config_server",
"production": "NODE_ENV=production rspack $npm_package_config_client && NODE_ENV=production rspack $npm_package_config_server",
"start": "yarn build && node $npm_package_main",
"test": "jest --coverage",
"typecheck": "tsc --noEmit",
Expand Down Expand Up @@ -73,8 +73,11 @@
"devDependencies": {
"@eslint/js": "^9.9.0",
"@loadable/webpack-plugin": "^5.2.2",
"@pmmmwh/react-refresh-webpack-plugin": "^0.5.15",
"@prisma/client": "^5.18.0",
"@rsdoctor/rspack-plugin": "^0.4.7",
"@rspack/cli": "^1.0.14",
"@rspack/core": "^1.0.14",
"@rspack/plugin-react-refresh": "^1.0.0",
"@svgr/webpack": "^8.1.0",
"@swc/core": "^1.7.11",
"@swc/jest": "^0.2.36",
Expand Down Expand Up @@ -102,15 +105,13 @@
"eslint-plugin-import": "^2.31.0",
"eslint-plugin-prettier": "^5.2.1",
"eslint-plugin-react": "^7.35.0",
"file-loader": "^6.2.0",
"globals": "^15.9.0",
"gulp": "^5.0.0",
"gulp-nodemon": "^2.4.1",
"identity-obj-proxy": "^3.0.0",
"jest": "^29.3.1",
"jest-environment-jsdom": "^29.3.1",
"jest-transform-stub": "^2.0.0",
"mini-css-extract-plugin": "^2.9.0",
"nodemon": "^3.1.4",
"postcss": "^8.4.41",
"postcss-combine-media-query": "^1.0.1",
Expand All @@ -124,14 +125,9 @@
"sass-embedded": "^1.77.8",
"sass-loader": "^16.0.0",
"stylelint": "^16.8.2",
"swc-loader": "^0.2.6",
"terser-webpack-plugin": "^5.3.6",
"swc-plugin-add-display-name": "^0.5.0",
"typescript": "^5.5.4",
"typescript-eslint": "^8.1.0",
"url-loader": "^4.1.1",
"webpack": "^5.93.0",
"webpack-bundle-analyzer": "^4.10.2",
"webpack-cli": "^5.0.0",
"webpack-dev-middleware": "^7.3.0",
"webpack-hot-middleware": "^2.26.1",
"webpack-merge": "^6.0.1",
Expand Down
6 changes: 4 additions & 2 deletions server/index.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,13 @@ import { dirname, resolve } from 'path';
import { fileURLToPath } from 'url';

import { config } from '../config/config.cjs';
import { requestHandler } from '../dist/request-handler.cjs';
import pkg from '../dist/request-handler.cjs';

import { register } from './register.mjs';
import { routes } from './routes.mjs';

const { requestHandler } = pkg;

const __dirname = dirname(fileURLToPath(import.meta.url));

const statsFile = resolve(__dirname, '../dist/loadable-stats.json');
Expand Down Expand Up @@ -55,7 +57,7 @@ app.setErrorHandler(async (error, request, reply) => {
Sentry.captureException(error);
}

reply.status(500).send({ error: 'Something went wrong' });
reply.status(500).send(error);
});

register(app);
Expand Down
4 changes: 2 additions & 2 deletions src/root/client.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,12 @@ import type { InitOptions } from 'i18next';

i18next.use(Fetch);
i18next.use(initReactI18next);
i18next.init(options() as InitOptions);

const ExtendedApp = withSSR()(App);
const store = initializeState(window.__initialData__);

loadableReady(() => {
loadableReady(async () => {
await i18next.init(options() as InitOptions);
hydrateRoot(
document.getElementById('root') as HTMLDivElement,
<Provider store={store}>
Expand Down
Loading

0 comments on commit c68ebba

Please sign in to comment.