From e05d2bab75bc6d3462f0a581a46cfe50b1a902ce Mon Sep 17 00:00:00 2001
From: Innei
Date: Sat, 5 Oct 2024 00:37:08 +0800
Subject: [PATCH] refactor: vite config and re-optimize chunks
Signed-off-by: Innei
---
apps/renderer/package.json | 3 -
apps/renderer/src/pages/(external)/debug.tsx | 33 ----
configs/vite.render.config.ts | 142 +-----------------
eslint.config.mjs | 6 +-
.../{ => eslint}/eslint-check-i18n-json.js | 0
plugins/{ => eslint}/eslint-no-debug.js | 0
plugins/{ => eslint}/eslint-recursive-sort.js | 0
plugins/vite/custom-asset.ts | 39 +++++
plugins/vite/deps.ts | 33 ++++
plugins/vite/html-inject.ts | 29 ++++
plugins/vite/i18n-hmr.ts | 24 +++
plugins/vite/locales.ts | 64 ++++++++
plugins/vite/short-alias.ts | 57 +++++++
plugins/vite/tw-macro.ts | 54 +++++++
.../vite/utils}/i18n-completeness.ts | 6 +-
pnpm-lock.yaml | 33 ----
vite.config.ts | 75 +++++----
17 files changed, 358 insertions(+), 240 deletions(-)
delete mode 100644 apps/renderer/src/pages/(external)/debug.tsx
rename plugins/{ => eslint}/eslint-check-i18n-json.js (100%)
rename plugins/{ => eslint}/eslint-no-debug.js (100%)
rename plugins/{ => eslint}/eslint-recursive-sort.js (100%)
create mode 100644 plugins/vite/custom-asset.ts
create mode 100644 plugins/vite/deps.ts
create mode 100644 plugins/vite/html-inject.ts
create mode 100644 plugins/vite/i18n-hmr.ts
create mode 100644 plugins/vite/locales.ts
create mode 100644 plugins/vite/short-alias.ts
create mode 100644 plugins/vite/tw-macro.ts
rename {configs => plugins/vite/utils}/i18n-completeness.ts (87%)
diff --git a/apps/renderer/package.json b/apps/renderer/package.json
index 0854d9b8f1..a96edd51cc 100644
--- a/apps/renderer/package.json
+++ b/apps/renderer/package.json
@@ -20,7 +20,6 @@
"@lottiefiles/dotlottie-react": "0.9.0",
"@microflash/remark-callout-directives": "4.3.1",
"@mozilla/readability": "^0.5.0",
- "@radix-ui/react-alert-dialog": "1.1.1",
"@radix-ui/react-avatar": "1.1.0",
"@radix-ui/react-checkbox": "1.1.1",
"@radix-ui/react-context-menu": "2.2.1",
@@ -39,7 +38,6 @@
"@radix-ui/react-toast": "1.2.1",
"@radix-ui/react-tooltip": "1.1.2",
"@sentry/react": "8.32.0",
- "@sentry/vite-plugin": "2.22.4",
"@shikijs/transformers": "1.20.0",
"@t3-oss/env-core": "^0.11.1",
"@tanstack/query-sync-storage-persister": "5.56.2",
@@ -68,7 +66,6 @@
"immer": "10.1.1",
"jotai": "2.10.0",
"lethargy": "1.0.9",
- "linkedom": "^0.18.5",
"lodash-es": "4.17.21",
"masonic": "4.0.1",
"nanoid": "5.0.7",
diff --git a/apps/renderer/src/pages/(external)/debug.tsx b/apps/renderer/src/pages/(external)/debug.tsx
deleted file mode 100644
index 87853ec894..0000000000
--- a/apps/renderer/src/pages/(external)/debug.tsx
+++ /dev/null
@@ -1,33 +0,0 @@
-import Versions from "../../components/Versions"
-
-export function Component() {
- if (!import.meta.env.DEV) return null
- const ipcHandle = (): void => window.electron?.ipcRenderer.send("ping")
-
- return (
- <>
-
Powered by electron-vite
-
-
- Build an Electron app with React
- and TypeScript
-
-
- Please try pressing F12
to open the devTool
-
-
-
- >
- )
-}
diff --git a/configs/vite.render.config.ts b/configs/vite.render.config.ts
index 6cac5dba41..0e6567d187 100644
--- a/configs/vite.render.config.ts
+++ b/configs/vite.render.config.ts
@@ -1,96 +1,19 @@
-import fs, { readFileSync } from "node:fs"
-import path, { resolve } from "node:path"
+import { readFileSync } from "node:fs"
+import { resolve } from "node:path"
-import * as babel from "@babel/core"
-import generate from "@babel/generator"
-import { parse } from "@babel/parser"
-import * as t from "@babel/types"
import { sentryVitePlugin } from "@sentry/vite-plugin"
import react from "@vitejs/plugin-react"
-import { set } from "lodash-es"
import { prerelease } from "semver"
-import type { Plugin, UserConfig } from "vite"
+import type { UserConfig } from "vite"
+import { customI18nHmrPlugin } from "../plugins/vite/i18n-hmr"
+import { localesPlugin } from "../plugins/vite/locales"
+import { twMacro } from "../plugins/vite/tw-macro"
+import i18nCompleteness from "../plugins/vite/utils/i18n-completeness"
import { getGitHash } from "../scripts/lib"
-import i18nCompleteness from "./i18n-completeness"
const pkg = JSON.parse(readFileSync("package.json", "utf8"))
const isCI = process.env.CI === "true" || process.env.CI === "1"
-function localesPlugin(): Plugin {
- return {
- name: "locales-merge",
- enforce: "post",
- generateBundle(_options, bundle) {
- const localesDir = path.resolve(__dirname, "../locales")
- const namespaces = fs.readdirSync(localesDir).filter((dir) => dir !== ".DS_Store")
- const languageResources = {}
-
- namespaces.forEach((namespace) => {
- const namespacePath = path.join(localesDir, namespace)
- const files = fs.readdirSync(namespacePath).filter((file) => file.endsWith(".json"))
-
- files.forEach((file) => {
- const lang = path.basename(file, ".json")
- const filePath = path.join(namespacePath, file)
- const content = JSON.parse(fs.readFileSync(filePath, "utf-8"))
-
- if (!languageResources[lang]) {
- languageResources[lang] = {}
- }
-
- const obj = {}
-
- const keys = Object.keys(content as object)
- for (const accessorKey of keys) {
- set(obj, accessorKey, (content as any)[accessorKey])
- }
-
- languageResources[lang][namespace] = obj
- })
- })
-
- Object.entries(languageResources).forEach(([lang, resources]) => {
- const fileName = `locales/${lang}.js`
-
- const content = `export default ${JSON.stringify(resources)};`
-
- this.emitFile({
- type: "asset",
- fileName,
- source: content,
- })
- })
-
- // Remove original JSON chunks
- Object.keys(bundle).forEach((key) => {
- if (key.startsWith("locales/") && key.endsWith(".json")) {
- delete bundle[key]
- }
- })
- },
- }
-}
-
-function customI18nHmrPlugin(): Plugin {
- return {
- name: "custom-i18n-hmr",
- handleHotUpdate({ file, server }) {
- if (file.endsWith(".json") && file.includes("locales")) {
- server.ws.send({
- type: "custom",
- event: "i18n-update",
- data: {
- file,
- content: readFileSync(file, "utf-8"),
- },
- })
-
- // return empty array to prevent the default HMR
- return []
- }
- },
- }
-}
export const viteRenderBaseConfig = {
resolve: {
@@ -130,7 +53,7 @@ export const viteRenderBaseConfig = {
}),
localesPlugin(),
- viteTwToRawString(),
+ twMacro(),
customI18nHmrPlugin(),
],
define: {
@@ -147,52 +70,3 @@ export const viteRenderBaseConfig = {
I18N_COMPLETENESS_MAP: JSON.stringify({ ...i18nCompleteness, en: 100 }),
},
} satisfies UserConfig
-
-function viteTwToRawString(): Plugin {
- return {
- name: "vite-plugin-tw-to-raw-string",
-
- transform(code, id) {
- // Only Process .tsx .ts .jsx .js files
- if (!/\.[jt]sx?$/.test(id)) {
- return null
- }
- // Parse the code using Babel's parser with TypeScript support
- const ast = parse(code, {
- sourceType: "module",
- plugins: ["jsx", "typescript"], // Add typescript support
- })
-
- babel.traverse(ast, {
- TaggedTemplateExpression(path) {
- if (t.isIdentifier(path.node.tag, { name: "tw" })) {
- const { quasi } = path.node
- if (t.isTemplateLiteral(quasi)) {
- // Create a new template literal by combining quasis and expressions
- const quasis = quasi.quasis.map((q) => q.value.raw)
-
- // Replace the tagged template expression with the new template literal as a string
- path.replaceWith(
- t.templateLiteral(
- quasis.map((q, i) =>
- t.templateElement({ raw: q, cooked: q }, i === quasis.length - 1),
- ),
- quasi.expressions,
- ),
- )
- }
- }
- },
- })
-
- // Generate the transformed code from the modified AST
- // @ts-expect-error
- const output = generate.default(ast, {}, code)
-
- return {
- code: output.code,
- map: null, // Source map generation can be added if necessary
- }
- },
- }
-}
diff --git a/eslint.config.mjs b/eslint.config.mjs
index 1fa926d369..b09b7d8144 100644
--- a/eslint.config.mjs
+++ b/eslint.config.mjs
@@ -1,9 +1,9 @@
// @ts-check
import { defineConfig } from "eslint-config-hyoban"
-import checkI18nJson from "./plugins/eslint-check-i18n-json.js"
-import noDebug from "./plugins/eslint-no-debug.js"
-import recursiveSort from "./plugins/eslint-recursive-sort.js"
+import checkI18nJson from "./plugins/eslint/eslint-check-i18n-json.js"
+import noDebug from "./plugins/eslint/eslint-no-debug.js"
+import recursiveSort from "./plugins/eslint/eslint-recursive-sort.js"
export default defineConfig(
{
diff --git a/plugins/eslint-check-i18n-json.js b/plugins/eslint/eslint-check-i18n-json.js
similarity index 100%
rename from plugins/eslint-check-i18n-json.js
rename to plugins/eslint/eslint-check-i18n-json.js
diff --git a/plugins/eslint-no-debug.js b/plugins/eslint/eslint-no-debug.js
similarity index 100%
rename from plugins/eslint-no-debug.js
rename to plugins/eslint/eslint-no-debug.js
diff --git a/plugins/eslint-recursive-sort.js b/plugins/eslint/eslint-recursive-sort.js
similarity index 100%
rename from plugins/eslint-recursive-sort.js
rename to plugins/eslint/eslint-recursive-sort.js
diff --git a/plugins/vite/custom-asset.ts b/plugins/vite/custom-asset.ts
new file mode 100644
index 0000000000..5fa0ccd57d
--- /dev/null
+++ b/plugins/vite/custom-asset.ts
@@ -0,0 +1,39 @@
+import path from "node:path"
+
+import fs from "fs-extra"
+import type { Plugin } from "vite"
+
+export default function customAssetOutput(options: {
+ dependencies: Record
+}): Plugin {
+ const { dependencies = {} } = options
+
+ return {
+ name: "vite-plugin-custom-asset-output",
+
+ async generateBundle(_, bundle) {
+ for (const [dependencyName, config] of Object.entries(dependencies)) {
+ const { sourceDir, targetDir } = config
+
+ for (const fileName in bundle) {
+ const file = bundle[fileName]
+
+ if (
+ file.type === "asset" &&
+ file.name &&
+ file.name.startsWith(`${dependencyName}/${sourceDir}`)
+ ) {
+ const newFileName = file.name.replace(`${dependencyName}/${sourceDir}`, targetDir)
+
+ file.fileName = newFileName
+
+ await fs.ensureDir(path.dirname(newFileName))
+
+ bundle[newFileName] = file
+ delete bundle[fileName]
+ }
+ }
+ }
+ },
+ }
+}
diff --git a/plugins/vite/deps.ts b/plugins/vite/deps.ts
new file mode 100644
index 0000000000..ebf8ee6fdf
--- /dev/null
+++ b/plugins/vite/deps.ts
@@ -0,0 +1,33 @@
+import type { Plugin, UserConfig } from "vite"
+
+export function createDependencyChunksPlugin(dependencies: string[] | string[][]): Plugin {
+ return {
+ name: "dependency-chunks",
+ config(config: UserConfig) {
+ config.build = config.build || {}
+ config.build.rollupOptions = config.build.rollupOptions || {}
+ config.build.rollupOptions.output = config.build.rollupOptions.output || {}
+
+ const { output } = config.build.rollupOptions
+ const outputConfig = Array.isArray(output) ? output[0] : output
+ outputConfig.manualChunks = outputConfig.manualChunks || {}
+ outputConfig.assetFileNames = "assets/[name].[hash][extname]"
+ outputConfig.chunkFileNames = (chunkInfo) => {
+ return chunkInfo.name.startsWith("vendor/") ? "[name].[hash].js" : "assets/[name].[hash].js"
+ }
+
+ const manualChunks = Array.isArray(output) ? output[0].manualChunks : output.manualChunks
+
+ if (typeof manualChunks !== "object") return
+
+ dependencies.forEach((dep, index) => {
+ if (Array.isArray(dep)) {
+ const chunkName = `vendor/a${index}`
+ manualChunks[chunkName] = dep
+ } else {
+ manualChunks[`vendor/${dep}`] = [dep]
+ }
+ })
+ },
+ }
+}
diff --git a/plugins/vite/html-inject.ts b/plugins/vite/html-inject.ts
new file mode 100644
index 0000000000..6a3f338729
--- /dev/null
+++ b/plugins/vite/html-inject.ts
@@ -0,0 +1,29 @@
+import type { PluginOption } from "vite"
+
+import type { env as EnvType } from "../../packages/shared/src/env"
+
+export function htmlInjectPlugin(env: typeof EnvType): PluginOption {
+ return {
+ name: "html-transform",
+ enforce: "post",
+ transformIndexHtml(html) {
+ return html.replace(
+ "",
+ ``,
+ )
+ },
+ }
+}
diff --git a/plugins/vite/i18n-hmr.ts b/plugins/vite/i18n-hmr.ts
new file mode 100644
index 0000000000..c9ce5e5a86
--- /dev/null
+++ b/plugins/vite/i18n-hmr.ts
@@ -0,0 +1,24 @@
+import { readFileSync } from "node:fs"
+
+import type { Plugin } from "vite"
+
+export function customI18nHmrPlugin(): Plugin {
+ return {
+ name: "custom-i18n-hmr",
+ handleHotUpdate({ file, server }) {
+ if (file.endsWith(".json") && file.includes("locales")) {
+ server.ws.send({
+ type: "custom",
+ event: "i18n-update",
+ data: {
+ file,
+ content: readFileSync(file, "utf-8"),
+ },
+ })
+
+ // return empty array to prevent the default HMR
+ return []
+ }
+ },
+ }
+}
diff --git a/plugins/vite/locales.ts b/plugins/vite/locales.ts
new file mode 100644
index 0000000000..45b7b24331
--- /dev/null
+++ b/plugins/vite/locales.ts
@@ -0,0 +1,64 @@
+import fs from "node:fs"
+import path, { dirname } from "node:path"
+import { fileURLToPath } from "node:url"
+
+import { set } from "lodash-es"
+import type { Plugin } from "vite"
+
+export function localesPlugin(): Plugin {
+ return {
+ name: "locales-merge",
+ enforce: "post",
+ generateBundle(_options, bundle) {
+ const __dirname = dirname(fileURLToPath(import.meta.url))
+
+ const localesDir = path.resolve(__dirname, "../../locales")
+
+ const namespaces = fs.readdirSync(localesDir).filter((dir) => dir !== ".DS_Store")
+ const languageResources = {}
+
+ namespaces.forEach((namespace) => {
+ const namespacePath = path.join(localesDir, namespace)
+ const files = fs.readdirSync(namespacePath).filter((file) => file.endsWith(".json"))
+
+ files.forEach((file) => {
+ const lang = path.basename(file, ".json")
+ const filePath = path.join(namespacePath, file)
+ const content = JSON.parse(fs.readFileSync(filePath, "utf-8"))
+
+ if (!languageResources[lang]) {
+ languageResources[lang] = {}
+ }
+
+ const obj = {}
+
+ const keys = Object.keys(content as object)
+ for (const accessorKey of keys) {
+ set(obj, accessorKey, (content as any)[accessorKey])
+ }
+
+ languageResources[lang][namespace] = obj
+ })
+ })
+
+ Object.entries(languageResources).forEach(([lang, resources]) => {
+ const fileName = `locales/${lang}.js`
+
+ const content = `export default ${JSON.stringify(resources)};`
+
+ this.emitFile({
+ type: "asset",
+ fileName,
+ source: content,
+ })
+ })
+
+ // Remove original JSON chunks
+ Object.keys(bundle).forEach((key) => {
+ if (key.startsWith("locales/") && key.endsWith(".json")) {
+ delete bundle[key]
+ }
+ })
+ },
+ }
+}
diff --git a/plugins/vite/short-alias.ts b/plugins/vite/short-alias.ts
new file mode 100644
index 0000000000..988219cafa
--- /dev/null
+++ b/plugins/vite/short-alias.ts
@@ -0,0 +1,57 @@
+import type { Plugin } from "vite"
+
+export function shortAliasPlugin(): Plugin {
+ const aliasMap = new Map()
+ let aliasCounter = 0
+
+ function generateShortAlias(): string {
+ const chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ let result = "_"
+ let counter = aliasCounter++
+
+ do {
+ result += chars[counter % chars.length]
+ counter = Math.floor(counter / chars.length)
+ } while (counter > 0)
+
+ return result
+ }
+
+ return {
+ name: "short-alias",
+ renderChunk(code, chunk) {
+ if (chunk.fileName.startsWith("vendor/")) return code
+ const importRegex = /import\s*(\{[^}]+\})\s*from\s*(['"])([^'"]+)\2/g
+
+ return code.replaceAll(importRegex, (match, imports, quote, source) => {
+ // Only process imports with curly braces
+ if (!imports.startsWith("{") || !imports.endsWith("}")) {
+ return match
+ }
+
+ const newImports = imports
+ .slice(1, -1) // Remove the curly braces
+ .split(",")
+ .map((imp) => {
+ const [original, alias] = imp.trim().split(/\s+as\s+/)
+ if (alias) {
+ // If an alias already exists, keep it or shorten it if it's too long
+ if (alias.length > 3) {
+ let shortAlias = aliasMap.get(alias)
+ if (!shortAlias) {
+ shortAlias = generateShortAlias()
+ aliasMap.set(alias, shortAlias)
+ }
+ return `${original} as ${shortAlias}`
+ }
+ return imp.trim()
+ }
+ return imp.trim()
+ })
+ .join(", ")
+
+ return `import {${newImports}} from ${quote}${source}${quote}`
+ })
+ },
+ }
+}
diff --git a/plugins/vite/tw-macro.ts b/plugins/vite/tw-macro.ts
new file mode 100644
index 0000000000..5207e09818
--- /dev/null
+++ b/plugins/vite/tw-macro.ts
@@ -0,0 +1,54 @@
+import * as babel from "@babel/core"
+import generate from "@babel/generator"
+import { parse } from "@babel/parser"
+import * as t from "@babel/types"
+import type { Plugin } from "vite"
+
+export function twMacro(): Plugin {
+ return {
+ name: "vite-plugin-tw-to-raw-string",
+
+ transform(code, id) {
+ // Only Process .tsx .ts .jsx .js files
+ if (!/\.[jt]sx?$/.test(id)) {
+ return null
+ }
+ // Parse the code using Babel's parser with TypeScript support
+ const ast = parse(code, {
+ sourceType: "module",
+ plugins: ["jsx", "typescript"], // Add typescript support
+ })
+
+ babel.traverse(ast, {
+ TaggedTemplateExpression(path) {
+ if (t.isIdentifier(path.node.tag, { name: "tw" })) {
+ const { quasi } = path.node
+ if (t.isTemplateLiteral(quasi)) {
+ // Create a new template literal by combining quasis and expressions
+ const quasis = quasi.quasis.map((q) => q.value.raw)
+
+ // Replace the tagged template expression with the new template literal as a string
+ path.replaceWith(
+ t.templateLiteral(
+ quasis.map((q, i) =>
+ t.templateElement({ raw: q, cooked: q }, i === quasis.length - 1),
+ ),
+ quasi.expressions,
+ ),
+ )
+ }
+ }
+ },
+ })
+
+ // Generate the transformed code from the modified AST
+ // @ts-expect-error
+ const output = generate.default(ast, {}, code)
+
+ return {
+ code: output.code,
+ map: null, // Source map generation can be added if necessary
+ }
+ },
+ }
+}
diff --git a/configs/i18n-completeness.ts b/plugins/vite/utils/i18n-completeness.ts
similarity index 87%
rename from configs/i18n-completeness.ts
rename to plugins/vite/utils/i18n-completeness.ts
index 3de328b319..479e7790a5 100644
--- a/configs/i18n-completeness.ts
+++ b/plugins/vite/utils/i18n-completeness.ts
@@ -1,5 +1,6 @@
import fs from "node:fs"
-import path from "node:path"
+import path, { dirname } from "node:path"
+import { fileURLToPath } from "node:url"
type LanguageCompletion = Record
@@ -55,6 +56,7 @@ function calculateCompleteness(localesDir: string): LanguageCompletion {
return completeness
}
+const __dirname = dirname(fileURLToPath(import.meta.url))
-const i18n = calculateCompleteness(path.resolve(__dirname, "../locales"))
+const i18n = calculateCompleteness(path.resolve(__dirname, "../../../locales"))
export default i18n
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 0bf0241123..dd479186d2 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -351,9 +351,6 @@ importers:
'@mozilla/readability':
specifier: ^0.5.0
version: 0.5.0(patch_hash=fgkvsbckled47trggkhdkimzbm)
- '@radix-ui/react-alert-dialog':
- specifier: 1.1.1
- version: 1.1.1(@types/react-dom@18.3.0)(@types/react@18.3.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
'@radix-ui/react-avatar':
specifier: 1.1.0
version: 1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
@@ -408,9 +405,6 @@ importers:
'@sentry/react':
specifier: 8.32.0
version: 8.32.0(react@18.3.1)
- '@sentry/vite-plugin':
- specifier: 2.22.4
- version: 2.22.4(encoding@0.1.13)
'@shikijs/transformers':
specifier: 1.20.0
version: 1.20.0
@@ -2398,19 +2392,6 @@ packages:
'@radix-ui/primitive@1.1.0':
resolution: {integrity: sha512-4Z8dn6Upk0qk4P74xBhZ6Hd/w0mPEzOOLxy4xiPXOXqjF7jZS0VAKk7/x/H6FyY2zCkYJqePf1G5KmkmNJ4RBA==}
- '@radix-ui/react-alert-dialog@1.1.1':
- resolution: {integrity: sha512-wmCoJwj7byuVuiLKqDLlX7ClSUU0vd9sdCeM+2Ls+uf13+cpSJoMgwysHq1SGVVkJj5Xn0XWi1NoRCdkMpr6Mw==}
- peerDependencies:
- '@types/react': '*'
- '@types/react-dom': '*'
- react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
- react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
- peerDependenciesMeta:
- '@types/react':
- optional: true
- '@types/react-dom':
- optional: true
-
'@radix-ui/react-arrow@1.1.0':
resolution: {integrity: sha512-FmlW1rCg7hBpEBwFbjHwCW6AmWLQM6g/v0Sn8XbP9NvmSZ2San1FpQeyPtufzOMSIx7Y4dzjlHoifhp+7NkZhw==}
peerDependencies:
@@ -11099,20 +11080,6 @@ snapshots:
'@radix-ui/primitive@1.1.0': {}
- '@radix-ui/react-alert-dialog@1.1.1(@types/react-dom@18.3.0)(@types/react@18.3.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
- dependencies:
- '@radix-ui/primitive': 1.1.0
- '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.3.10)(react@18.3.1)
- '@radix-ui/react-context': 1.1.0(@types/react@18.3.10)(react@18.3.1)
- '@radix-ui/react-dialog': 1.1.1(@types/react-dom@18.3.0)(@types/react@18.3.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
- '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.0)(@types/react@18.3.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
- '@radix-ui/react-slot': 1.1.0(@types/react@18.3.10)(react@18.3.1)
- react: 18.3.1
- react-dom: 18.3.1(react@18.3.1)
- optionalDependencies:
- '@types/react': 18.3.10
- '@types/react-dom': 18.3.0
-
'@radix-ui/react-arrow@1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
dependencies:
'@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.0)(@types/react@18.3.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
diff --git a/vite.config.ts b/vite.config.ts
index 559d8fe526..e4481e761c 100644
--- a/vite.config.ts
+++ b/vite.config.ts
@@ -9,38 +9,14 @@ import { analyzer } from "vite-bundle-analyzer"
import mkcert from "vite-plugin-mkcert"
import { viteRenderBaseConfig } from "./configs/vite.render.config"
-import type { env as EnvType } from "./src/env"
+import type { env as EnvType } from "./packages/shared/src/env"
+import { createDependencyChunksPlugin } from "./plugins/vite/deps"
+import { htmlInjectPlugin } from "./plugins/vite/html-inject"
const __dirname = fileURLToPath(new URL(".", import.meta.url))
const isCI = process.env.CI === "true" || process.env.CI === "1"
const ROOT = "./apps/renderer"
-function htmlPlugin(env: typeof EnvType): PluginOption {
- return {
- name: "html-transform",
- enforce: "post",
- transformIndexHtml(html) {
- return html.replace(
- "",
- ``,
- )
- },
- }
-}
-
const devPrint = (): PluginOption => ({
name: "dev-print",
configureServer(server: ViteDevServer) {
@@ -78,10 +54,6 @@ export default ({ mode }) => {
main: resolve(ROOT, "/index.html"),
__debug_proxy: resolve(ROOT, "/__debug_proxy.html"),
},
- output: {
- // 10KB
- experimentalMinChunkSize: 10_000,
- },
},
},
server: {
@@ -99,12 +71,51 @@ export default ({ mode }) => {
modernTargets: ">0.3%, last 2 versions, Firefox ESR, not dead",
modernPolyfills: ["es.array.find-last-index", "es.array.find-last"],
}),
- htmlPlugin(typedEnv),
+ htmlInjectPlugin(typedEnv),
mkcert(),
devPrint(),
+ createDependencyChunksPlugin([
+ ["react", "react-dom"],
+ ["zustand", "jotai", "use-context-selector", "immer", "dexie"],
+ [
+ "remark-directive",
+ "remark-gfm",
+ "remark-parse",
+ "remark-stringify",
+ "remark-rehype",
+ "@microflash/remark-callout-directives",
+ "remark-gh-alerts",
+ ],
+ [
+ "rehype-parse",
+ "rehype-sanitize",
+ "rehype-stringify",
+ "rehype-infer-description-meta",
+ "hast-util-to-jsx-runtime",
+ "hast-util-to-text",
+ ],
+ ["vfile", "unified"],
+ ["lodash-es"],
+ ["framer-motion"],
+ ["clsx", "tailwind-merge", "class-variance-authority"],
+ ["@radix-ui/react-dialog", "re-resizable"],
+ ["i18next", "i18next-browser-languagedetector", "react-i18next"],
+ [
+ "@tanstack/react-query",
+ "@tanstack/react-query-persist-client",
+ "@tanstack/query-sync-storage-persister",
+ ],
+ ["blurhash", "react-blurhash"],
+ ["tldts"],
+ ["shiki", "@shikijs/transformers"],
+ ["@sentry/react", "posthog-js"],
+ ["zod", "react-hook-form", "@hookform/resolvers"],
+ ]),
+ // shortAliasPlugin(),
process.env.ANALYZER && analyzer(),
],
+
define: {
...viteRenderBaseConfig.define,
ELECTRON: "false",