build: replace webpack with rspack

This commit is contained in:
Lukas Obermann
2024-08-30 16:27:13 +02:00
parent 40c0336611
commit 3c4b9a90ac
12 changed files with 4363 additions and 961 deletions
+4130 -743
View File
File diff suppressed because it is too large Load Diff
+5 -5
View File
@@ -34,6 +34,8 @@
"@electron/notarize": "^2.1.0",
"@eslint/eslintrc": "^2.1.2",
"@eslint/js": "^8.52.0",
"@rspack/cli": "^1.0.0",
"@rspack/core": "^1.0.0",
"@types/mousetrap": "^1.6.13",
"@types/node": "^20.8.10",
"@types/react": "^18.2.33",
@@ -63,9 +65,7 @@
"standard-version": "^9.5.0",
"ts-loader": "^9.5.0",
"tsx": "^3.14.0",
"typescript": "^5.2.2",
"webpack": "^5.89.0",
"webpack-cli": "^5.1.4"
"typescript": "^5.2.2"
},
"scripts": {
"prerelease:win": "set NODE_ENV=development && node ./build/build.js --win --prerelease",
@@ -74,8 +74,8 @@
"stable:win": "set NODE_ENV=production && node ./build/build.js --win --stable",
"stable:linux": "NODE_ENV=production node ./build/build.js --linux --stable",
"stable:mac": "NODE_ENV=production node ./build/build.js --mac --stable",
"js:build": "webpack",
"js:watch": "webpack -w",
"js:build": "rspack build",
"js:watch": "rspack build -w",
"ts:build": "tsc",
"ts:watch": "tsc -w",
"createschemas": "otjsmd",
+122
View File
@@ -0,0 +1,122 @@
// @ts-check
import { dirname, resolve } from "node:path"
import { fileURLToPath } from "node:url"
import { getOptimization } from "./rspack.optimization.js"
import { rendererPlugins } from "./rspack.plugins.js"
import { rules } from "./rspack.rules.js"
/**
* @param {string} name
* @param {EnvironmentMode} mode
* @returns {import("@rspack/core").Configuration[]}
*/
const createRendererConfig = (name, mode) => [
{
name: `renderer_${name}`,
mode,
entry: {
[`renderer_${name}`]: `./src/${name}_window/index.tsx`,
},
target: "electron27-renderer",
optimization: getOptimization(`renderer_${name}`),
module: {
rules: rules,
},
resolve: {
symlinks: false,
conditionNames: ["browser", "default", "import", "require"],
},
output: {
path: resolve(dirname(fileURLToPath(import.meta.url)), ".webpack"),
filename: "[name].js",
globalObject: "globalThis",
},
plugins: rendererPlugins(mode),
externalsPresets: {
electronRenderer: true,
},
profile: true,
devtool: "source-map",
},
{
name: `renderer_${name}_preload`,
mode,
entry: {
[`renderer_${name}_preload`]: `./src/${name}_window_preload/index.ts`,
},
target: "electron27-preload",
module: {
rules: rules,
},
resolve: {
symlinks: false,
},
output: {
path: resolve(dirname(fileURLToPath(import.meta.url)), ".webpack"),
filename: "[name].cjs",
},
},
]
/**
* @typedef {"development" | "production"} EnvironmentMode
* @returns {import("@rspack/core").Configuration[]}
*/
export default () => {
/** @type {EnvironmentMode} */
const mode = process.env.NODE_ENV === "production" ? "production" : "development"
return [
{
name: "main",
mode,
entry: {
main: "./src/main/index.ts",
},
target: "electron27-main",
optimization: getOptimization("main"),
module: {
rules: rules,
},
resolve: {
symlinks: false,
},
output: {
path: resolve(dirname(fileURLToPath(import.meta.url)), ".webpack"),
filename: "[name].cjs",
},
externalsPresets: {
electronMain: true,
},
},
{
name: "database",
mode,
entry: {
database: "./src/database/index.ts",
},
target: "electron27-main",
optimization: getOptimization("database"),
module: {
rules: rules,
},
resolve: {
symlinks: false,
},
output: {
path: resolve(dirname(fileURLToPath(import.meta.url)), ".webpack"),
filename: "[name].cjs",
},
externalsPresets: {
electronMain: true,
},
externals: {
"optolith-database-schema": "module optolith-database-schema",
},
},
...createRendererConfig("main", mode),
...createRendererConfig("updater", mode),
...createRendererConfig("settings", mode),
]
}
@@ -2,7 +2,7 @@
/**
* @param {string} processType
* @returns {Required<import("webpack").Configuration>["optimization"]}
* @returns {import("@rspack/core").Configuration["optimization"]}
*/
export const getOptimization = (processType) => ({
splitChunks: {
@@ -11,14 +11,14 @@ export const getOptimization = (processType) => ({
default: {
name: processType,
minChunks: 2,
priority: -20
priority: -20,
},
defaultVendors: {
name: `${processType}_vendors`,
test: /[\\/]node_modules[\\/]/,
priority: -10,
reuseExistingChunk: true,
}
}
}
},
},
},
})
+19
View File
@@ -0,0 +1,19 @@
// @ts-check
import rspack from "@rspack/core"
/**
*
* @param {import("./rspack.config.js").EnvironmentMode} mode
* @returns {import("@rspack/core").Configuration["plugins"]}
*/
export const rendererPlugins = (mode) => [
new rspack.HtmlRspackPlugin({
filename: "[name].html",
template: "./src/template.html",
}),
new rspack.CssExtractRspackPlugin({
filename: `assets/css/${mode === "development" ? "[name].css" : "[name].[hash].css"}`,
chunkFilename: `assets/css/${mode === "development" ? "[id].css" : "[id].[hash].css"}`,
}),
]
+71
View File
@@ -0,0 +1,71 @@
// @ts-check
import rspack from "@rspack/core"
/**
* @type {Required<import("@rspack/core").ModuleOptions>["rules"]}
*/
export const rules = [
{
test: /\.tsx?$/,
exclude: [/node_modules/],
loader: "builtin:swc-loader",
resolve: {
extensions: [".ts", ".tsx", ".js"],
},
options: {
jsc: {
parser: {
syntax: 'typescript',
},
transform: {
react: {
runtime: 'automatic',
throwIfNamespace: true,
useBuiltins: false,
},
},
},
},
type: 'javascript/auto',
},
{
test: /\.(png|jpe?g|svg)$/i,
type: "asset/resource",
generator: {
filename: "assets/images/[name].[hash][ext][query]",
},
},
{
test: /\.(icns|ico)$/i,
type: "asset/resource",
generator: {
filename: "assets/icons/[name].[hash][ext][query]",
},
},
{
test: /\.(ttf|otf|woff2?)$/i,
type: "asset/resource",
generator: {
filename: "assets/fonts/[name].[hash][ext][query]",
},
},
{
test: /\.(css|sass|scss)$/,
use: [
rspack.CssExtractRspackPlugin.loader,
"css-loader",
"resolve-url-loader",
{
loader: "sass-loader",
options: {
sourceMap: true,
},
},
],
generator: {
filename: "assets/css/[name].[hash][ext][query]",
},
type: "javascript/auto",
},
]
+2 -3
View File
@@ -1,7 +1,7 @@
import Debug from "debug"
import { join } from "node:path"
import { parentPort } from "node:process"
import * as databaseSchema from "optolith-database-schema"
import type * as databaseSchema from "optolith-database-schema"
import { getAbsoluteCachePaths, getAbsoluteEntityPaths } from "./contents/src/config.js"
const debug = Debug("util:database")
@@ -10,8 +10,7 @@ const root = join(appPath, "src", "database", "contents")
debug("loading database ...")
// fix dynamic webpack import
;(databaseSchema as unknown as { default: Promise<typeof databaseSchema> }).default
import("optolith-database-schema")
.then(async db => {
const raw = await db.getAllValidData(getAbsoluteEntityPaths(root), {
ajvOptions: { allErrors: true },
+9 -9
View File
@@ -2,7 +2,6 @@ import Debug from "debug"
import { BrowserWindow, app, ipcMain, shell } from "electron"
import windowStateKeeper from "electron-window-state"
import * as path from "node:path"
import * as url from "node:url"
import type { Database } from "../database/index.ts"
import { InitialSetupEventMessage } from "../main_window_preload/index.ts"
import { getGlobalSettings } from "../shared/settings/main.ts"
@@ -55,14 +54,15 @@ export const createMainWindow = async (database: Database) => {
debug("Manage browser window with state keeper")
mainWindowState.manage(mainWindow)
debug("Load url")
await mainWindow.loadURL(
url.format({
pathname: path.join(__dirname, "renderer_main.html"),
protocol: "file:",
slashes: true,
}),
)
debug("Load file")
try {
await mainWindow.loadFile(path.join(".webpack", "renderer_main.html"))
} catch (error) {
debug("Error loading file: %O", error)
}
debug("Loaded file")
// mainWindow.webContents.openDevTools()
-114
View File
@@ -1,114 +0,0 @@
// @ts-check
import { dirname, resolve } from "node:path"
import { fileURLToPath } from "node:url"
import { mode } from "./webpack.env.js"
import { getOptimization } from "./webpack.optimization.js"
import { rendererPlugins } from "./webpack.plugins.js"
import { rules } from "./webpack.rules.js"
/**
* @param {string} name
* @return {import("webpack").Configuration[]}
*/
const createRendererConfig = name => [
{
name: `renderer_${name}`,
mode,
entry: {
[`renderer_${name}`]: `./src/${name}_window/index.tsx`
},
target: "electron27-renderer",
optimization: getOptimization(`renderer_${name}`),
module: {
rules: rules
},
resolve: {
symlinks: false,
conditionNames: ["browser", "default", "import", "require"],
},
output: {
path: resolve(dirname(fileURLToPath(import.meta.url)), ".webpack"),
filename: "[name].js",
globalObject: "globalThis",
},
plugins: rendererPlugins,
externalsPresets: {
electronRenderer: true
},
profile: true,
devtool: "source-map",
},
{
name: `renderer_${name}_preload`,
mode,
entry: {
[`renderer_${name}_preload`]: `./src/${name}_window_preload/index.ts`
},
target: "electron27-preload",
module: {
rules: rules
},
resolve: {
symlinks: false
},
output: {
path: resolve(dirname(fileURLToPath(import.meta.url)), ".webpack"),
filename: "[name].cjs"
}
}
]
/** @type {import("webpack").Configuration[]} */
export default [
{
name: "main",
mode,
entry: {
main: "./src/main/index.ts"
},
target: "electron27-main",
optimization: getOptimization("main"),
module: {
rules: rules
},
resolve: {
symlinks: false
},
output: {
path: resolve(dirname(fileURLToPath(import.meta.url)), ".webpack"),
filename: "[name].cjs"
},
externalsPresets: {
electronMain: true
}
},
{
name: "database",
mode,
entry: {
database: "./src/database/index.ts"
},
target: "electron27-main",
optimization: getOptimization("database"),
module: {
rules: rules
},
resolve: {
symlinks: false
},
output: {
path: resolve(dirname(fileURLToPath(import.meta.url)), ".webpack"),
filename: "[name].cjs"
},
externalsPresets: {
electronMain: true
},
externals: {
"optolith-database-schema": "module optolith-database-schema",
}
},
...createRendererConfig("main"),
...createRendererConfig("updater"),
...createRendererConfig("settings"),
]
-2
View File
@@ -1,2 +0,0 @@
export const mode = process.env.NODE_ENV === "production" ? "production" : "development"
export const isDevelopment = mode === 'development'
-19
View File
@@ -1,19 +0,0 @@
// @ts-check
import HtmlWebpackPlugin from "html-webpack-plugin"
import MiniCssExtractPlugin from "mini-css-extract-plugin"
import { isDevelopment } from "./webpack.env.js"
/**
* @type {import("webpack").Configuration["plugins"]}
*/
export const rendererPlugins = [
new HtmlWebpackPlugin({
filename: "[name].html",
template: "./src/template.html"
}),
new MiniCssExtractPlugin({
filename: `assets/css/${isDevelopment ? '[name].css' : '[name].[hash].css'}`,
chunkFilename: `assets/css/${isDevelopment ? '[id].css' : '[id].[hash].css'}`
}),
]
-61
View File
@@ -1,61 +0,0 @@
// @ts-check
import MiniCssExtractPlugin from "mini-css-extract-plugin"
import { dirname, resolve } from "path"
import { fileURLToPath } from "url"
/**
* @type {Required<import("webpack").ModuleOptions>["rules"]}
*/
export const rules = [
{
test: /\.tsx?$/,
include: resolve(dirname(fileURLToPath(import.meta.url)), "src"),
loader: "ts-loader",
resolve: {
extensions: [".ts", ".tsx", ".js"]
},
options: {
configFile: "tsconfig.webpack.json",
transpileOnly: true
}
},
{
test: /\.(png|jpe?g|svg)$/i,
type: "asset/resource",
generator: {
filename: "assets/images/[name].[hash][ext][query]"
}
},
{
test: /\.(icns|ico)$/i,
type: "asset/resource",
generator: {
filename: "assets/icons/[name].[hash][ext][query]"
}
},
{
test: /\.(ttf|otf|woff2?)$/i,
type: "asset/resource",
generator: {
filename: "assets/fonts/[name].[hash][ext][query]"
}
},
{
test: /\.(css|sass|scss)$/,
use: [
MiniCssExtractPlugin.loader,
'css-loader',
'resolve-url-loader',
{
loader: 'sass-loader',
options: {
sourceMap: true,
},
}
],
generator: {
filename: "assets/css/[name].[hash][ext][query]"
}
},
]