From de7bf6a1ff65ef96e36843d5592117dc2d6aed5e Mon Sep 17 00:00:00 2001 From: cyfung1031 <44498510+cyfung1031@users.noreply.github.com> Date: Wed, 19 Nov 2025 17:07:11 +0900 Subject: [PATCH] =?UTF-8?q?rspack=20=E6=89=93=E5=8C=85=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 8 +- pnpm-lock.yaml | 34 +++--- rspack.config.ts | 134 +++++++++++++++++++--- src/pages/components/CodeEditor/index.tsx | 3 + src/pages/store/AppContext.tsx | 8 +- 5 files changed, 152 insertions(+), 35 deletions(-) diff --git a/package.json b/package.json index 2654b9512..384f84ab8 100644 --- a/package.json +++ b/package.json @@ -54,6 +54,7 @@ "@eslint/js": "9.38.0", "@rspack/cli": "^1.5.8", "@rspack/core": "^1.5.8", + "@swc/helpers": "^0.5.17", "@testing-library/jest-dom": "^6.6.3", "@testing-library/react": "^16.3.0", "@types/chrome": "^0.1.27", @@ -89,5 +90,10 @@ "unocss": "66.5.4", "vitest": "^3.2.4" }, - "packageManager": "pnpm@10.12.4" + "packageManager": "pnpm@10.12.4", + "sideEffects": [ + "**/*.css", + "**/*.scss", + "**/*.less" + ] } \ No newline at end of file diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a9f11f053..356299cba 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -95,10 +95,13 @@ importers: version: 9.38.0 '@rspack/cli': specifier: ^1.5.8 - version: 1.6.1(@rspack/core@1.6.1(@swc/helpers@0.5.13))(@types/express@4.17.21)(webpack@5.96.1) + version: 1.6.1(@rspack/core@1.6.1(@swc/helpers@0.5.17))(@types/express@4.17.21)(webpack@5.96.1) '@rspack/core': specifier: ^1.5.8 - version: 1.6.1(@swc/helpers@0.5.13) + version: 1.6.1(@swc/helpers@0.5.17) + '@swc/helpers': + specifier: ^0.5.17 + version: 0.5.17 '@testing-library/jest-dom': specifier: ^6.6.3 version: 6.6.3 @@ -179,7 +182,7 @@ importers: version: 8.5.6 postcss-loader: specifier: ^8.2.0 - version: 8.2.0(@rspack/core@1.6.1(@swc/helpers@0.5.13))(postcss@8.5.6)(typescript@5.9.3)(webpack@5.96.1) + version: 8.2.0(@rspack/core@1.6.1(@swc/helpers@0.5.17))(postcss@8.5.6)(typescript@5.9.3)(webpack@5.96.1) prettier: specifier: ^3.6.2 version: 3.6.2 @@ -1039,8 +1042,8 @@ packages: resolution: {integrity: sha512-VynGOEsVw2s8TAlLf/uESfrgfrq2+rcXB1muPJYBWbsm1Oa6r5qVQhjA5ggM6z/coYPrsVMgovl3Ff7Q7OCp1w==} engines: {node: '>=16.0.0'} - '@swc/helpers@0.5.13': - resolution: {integrity: sha512-UoKGxQ3r5kYI9dALKJapMmuK+1zWM/H17Z1+iwnNmzcJRnfFuevZs375TA5rW31pu4BS4NoSy1fRsexDXfWn5w==} + '@swc/helpers@0.5.17': + resolution: {integrity: sha512-5IKx/Y13RsYd+sauPb2x+U/xZikHjolzfuDgTAl/Tdf3Q8rslRvC19NKDLgAJQ6wsqADk10ntlv08nPFw/gO/A==} '@testing-library/dom@10.4.0': resolution: {integrity: sha512-pemlzrSESWbdAloYml3bAJMEfNh1Z7EduzqPKprCH5S341frlpYnUEW0H72dLxa6IsYr+mPno20GiSm+h9dEdQ==} @@ -4996,11 +4999,11 @@ snapshots: '@rspack/binding-win32-ia32-msvc': 1.6.1 '@rspack/binding-win32-x64-msvc': 1.6.1 - '@rspack/cli@1.6.1(@rspack/core@1.6.1(@swc/helpers@0.5.13))(@types/express@4.17.21)(webpack@5.96.1)': + '@rspack/cli@1.6.1(@rspack/core@1.6.1(@swc/helpers@0.5.17))(@types/express@4.17.21)(webpack@5.96.1)': dependencies: '@discoveryjs/json-ext': 0.5.7 - '@rspack/core': 1.6.1(@swc/helpers@0.5.13) - '@rspack/dev-server': 1.1.4(@rspack/core@1.6.1(@swc/helpers@0.5.13))(@types/express@4.17.21)(webpack@5.96.1) + '@rspack/core': 1.6.1(@swc/helpers@0.5.17) + '@rspack/dev-server': 1.1.4(@rspack/core@1.6.1(@swc/helpers@0.5.17))(@types/express@4.17.21)(webpack@5.96.1) exit-hook: 4.0.0 webpack-bundle-analyzer: 4.10.2 transitivePeerDependencies: @@ -5012,17 +5015,17 @@ snapshots: - webpack - webpack-cli - '@rspack/core@1.6.1(@swc/helpers@0.5.13)': + '@rspack/core@1.6.1(@swc/helpers@0.5.17)': dependencies: '@module-federation/runtime-tools': 0.21.2 '@rspack/binding': 1.6.1 '@rspack/lite-tapable': 1.0.1 optionalDependencies: - '@swc/helpers': 0.5.13 + '@swc/helpers': 0.5.17 - '@rspack/dev-server@1.1.4(@rspack/core@1.6.1(@swc/helpers@0.5.13))(@types/express@4.17.21)(webpack@5.96.1)': + '@rspack/dev-server@1.1.4(@rspack/core@1.6.1(@swc/helpers@0.5.17))(@types/express@4.17.21)(webpack@5.96.1)': dependencies: - '@rspack/core': 1.6.1(@swc/helpers@0.5.13) + '@rspack/core': 1.6.1(@swc/helpers@0.5.17) chokidar: 3.6.0 http-proxy-middleware: 2.0.9(@types/express@4.17.21) p-retry: 6.2.1 @@ -5039,10 +5042,9 @@ snapshots: '@rspack/lite-tapable@1.0.1': {} - '@swc/helpers@0.5.13': + '@swc/helpers@0.5.17': dependencies: tslib: 2.8.1 - optional: true '@testing-library/dom@10.4.0': dependencies: @@ -7603,14 +7605,14 @@ snapshots: possible-typed-array-names@1.0.0: {} - postcss-loader@8.2.0(@rspack/core@1.6.1(@swc/helpers@0.5.13))(postcss@8.5.6)(typescript@5.9.3)(webpack@5.96.1): + postcss-loader@8.2.0(@rspack/core@1.6.1(@swc/helpers@0.5.17))(postcss@8.5.6)(typescript@5.9.3)(webpack@5.96.1): dependencies: cosmiconfig: 9.0.0(typescript@5.9.3) jiti: 2.6.1 postcss: 8.5.6 semver: 7.7.2 optionalDependencies: - '@rspack/core': 1.6.1(@swc/helpers@0.5.13) + '@rspack/core': 1.6.1(@swc/helpers@0.5.17) webpack: 5.96.1 transitivePeerDependencies: - typescript diff --git a/rspack.config.ts b/rspack.config.ts index 793afe542..7802a251a 100644 --- a/rspack.config.ts +++ b/rspack.config.ts @@ -1,9 +1,11 @@ +/* eslint-disable no-fallthrough */ import * as path from "path"; import { defineConfig } from "@rspack/cli"; import { rspack } from "@rspack/core"; import { readFileSync } from "fs"; +import { NormalModule } from "@rspack/core"; -const pkg = JSON.parse(readFileSync("./package.json") as unknown as string); +const pkg = JSON.parse(readFileSync("./package.json", "utf-8")); const version = pkg.version; const dirname = path.resolve(); @@ -13,9 +15,12 @@ const isBeta = version.includes("-"); // Target browsers, see: https://github.com/browserslist/browserslist const targets = ["chrome >= 87", "edge >= 88", "firefox >= 78", "safari >= 14"]; -const src = `${dirname}/src`; -const dist = `${dirname}/dist`; -const assets = `${src}/assets`; +const src = path.join(dirname, "src"); +const dist = path.join(dirname, "dist"); +const assets = path.join(src, "assets"); + +// 排除这些文件,不进行分离 +const chunkExcludeSet = new Set(["editor.worker", "ts.worker", "linter.worker", "service_worker", "content", "inject"]); export default defineConfig({ ...(isDev @@ -92,6 +97,7 @@ export default defineConfig({ loader: "builtin:swc-loader", options: { jsc: { + externalHelpers: true, parser: { syntax: "typescript", tsx: true, @@ -212,25 +218,123 @@ export default defineConfig({ chunks: ["sandbox"], }), ].filter(Boolean), + experiments: { + css: true, + parallelCodeSplitting: true, + parallelLoader: true, + }, optimization: { minimizer: [ - new rspack.SwcJsMinimizerRspackPlugin({}), + new rspack.SwcJsMinimizerRspackPlugin({ + minimizerOptions: { + minify: !isDev, + mangle: { + keep_classnames: false, + keep_fnames: false, + keep_private_props: false, + ie8: false, + toplevel: true, + }, + module: true, + compress: { + passes: 2, + drop_console: false, + drop_debugger: !isDev, + ecma: 2020, + arrows: true, + dead_code: true, + ie8: false, + keep_classnames: false, + keep_fargs: false, + keep_fnames: false, + toplevel: true, + sequences: true, + hoist_props: false, + hoist_vars: false, + reduce_funcs: true, + reduce_vars: true, + pure_getters: "strict", + }, + format: { + comments: false, + beautify: false, + ecma: 2020, + }, + }, + }), new rspack.LightningCssMinimizerRspackPlugin({ minimizerOptions: { targets }, }), ], + removeAvailableModules: true, + removeEmptyChunks: true, + realContentHash: true, + sideEffects: true, + providedExports: true, + concatenateModules: true, + avoidEntryIife: true, + mergeDuplicateChunks: true, splitChunks: { - chunks: (chunk) => { - // 排除这些文件,不进行分离 - return !["editor.worker", "ts.worker", "linter.worker", "service_worker", "content", "inject"].includes( - chunk.name || "" - ); + minChunks: 1, + maxAsyncRequests: 30, + maxInitialRequests: 30, + minSize: { + javascript: 40 * 1024, // 40 kB + css: 10 * 1024, // 10 kB + }, + maxSize: { + javascript: 2 * 1024 * 1024, // 2 MB + css: 2 * 1024 * 1024, // 2 MB + }, + chunks: (chunk) => !chunkExcludeSet.has(chunk.name || ""), + hidePathInfo: false, + name: (module, _ctx) => { + if (module instanceof NormalModule) { + const p = `/${module.rawRequest}|/${module.resource}`.toLowerCase().replace(/[\\@/]+/g, "/"); + if (p.startsWith("/packages/message/")) return "lib_message"; + if (module.type === "json" && p.includes("translation.json")) return "translation_json"; + let tag = ""; + const idx = p.indexOf("/node_modules/"); + if (idx >= 0) { + let q = p.replace(/\.pnpm\/?/g, ""); + q = q.substring(idx); + q = q.replace(/\..*/, ""); + tag = q.split("/")[2] || ""; + } + if (module.type !== "css" && tag === "monaco-editor") return "lib_monaco"; + switch (tag) { + case "react-icons": + if (p.includes("/react-icons/tb")) return undefined; + case "react-dropzone": + case "react-dom": + case "react-i18next": + case "react-router-dom": + case "react-joyride": + case "react": + return `lib_${tag}`; + } + if (tag.startsWith("dnd-kit")) return "lib_dnd-kit"; + if (tag.startsWith("popper")) return "lib_react-joyride"; + if (tag.startsWith("react-")) return "lib_react"; + if (tag.startsWith("eslint")) return "lib_eslint"; + if (tag.startsWith("i18n")) return "lib_i18n"; + if ( + tag.startsWith("arco-design") || + tag === "resize-observer-polyfill" || + tag === "b-validate" || + tag === "lodash" || + tag === "focus-lock" + ) { + return "lib_arco_design"; + } + if (tag) { + // cron, dayjs, yaml, jszip, prettier, ... + if (tag === "luxon") return "lib_cron"; + return `lib_${tag}`; + } + return "chunk"; + } }, - minSize: 307200, - maxSize: 4194304, }, }, - experiments: { - css: true, - }, }); diff --git a/src/pages/components/CodeEditor/index.tsx b/src/pages/components/CodeEditor/index.tsx index 4fa13d33e..557098e35 100644 --- a/src/pages/components/CodeEditor/index.tsx +++ b/src/pages/components/CodeEditor/index.tsx @@ -2,6 +2,9 @@ import { editor, Range } from "monaco-editor"; import React, { useEffect, useImperativeHandle, useRef, useState } from "react"; import { globalCache, systemConfig } from "@App/pages/store/global"; import { LinterWorker } from "@App/pkg/utils/monaco-editor"; +import { fnPlaceHolder } from "@App/pages/store/AppContext"; + +fnPlaceHolder.setEditorTheme = (theme: string) => editor.setTheme(theme); type Props = { className?: string; diff --git a/src/pages/store/AppContext.tsx b/src/pages/store/AppContext.tsx index 4871af63c..40ee28a91 100644 --- a/src/pages/store/AppContext.tsx +++ b/src/pages/store/AppContext.tsx @@ -1,6 +1,8 @@ import React, { useState, createContext, type ReactNode, useEffect, useContext } from "react"; import { messageQueue } from "./global"; -import { editor } from "monaco-editor"; +export const fnPlaceHolder = { + setEditorTheme: null, +} as { setEditorTheme: ((theme: string) => void) | null }; export type ThemeParam = { theme: "auto" | "light" | "dark" }; export interface AppContextType { @@ -46,12 +48,12 @@ const setAppColorTheme = (theme: "light" | "dark" | "auto") => { case "dark": document.documentElement.classList.add("dark"); document.body.setAttribute("arco-theme", "dark"); - editor.setTheme("vs-dark"); + fnPlaceHolder.setEditorTheme?.("vs-dark"); break; case "light": document.documentElement.classList.remove("dark"); document.body.removeAttribute("arco-theme"); - editor.setTheme("vs"); + fnPlaceHolder.setEditorTheme?.("vs"); break; } };