From 3ca43b4282c3e3b2a717b5f861b82ce30302e82c Mon Sep 17 00:00:00 2001 From: thislight Date: Tue, 22 Oct 2024 22:55:53 +0800 Subject: [PATCH] i18n: chunk strings based on the key --- vite.config.ts | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/vite.config.ts b/vite.config.ts index ae43ff6..7881869 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -5,6 +5,50 @@ import suid from "@suid/vite-plugin"; import { VitePWA } from "vite-plugin-pwa"; import version from "vite-plugin-package-version"; import manifest from "./manifest.config"; +import { GetManualChunk } from "rollup"; + +/** + * Put all strings (/i18n/{key}.) into separated chunks based on the key. + */ +const chunkStrs: GetManualChunk = (id, { getModuleInfo }) => { + const match = /.*\/i18n\/(.*)\.[jt]s.*$/.exec(id); + if (match) { + const key = match[1]; + + const dependentEntryPoints = []; + + // we use a Set here so we handle each module at most once. This + // prevents infinite loops in case of circular dependencies + const idsToHandle = new Set(getModuleInfo(id)!.dynamicImporters); + + for (const moduleId of idsToHandle) { + const { isEntry, dynamicImporters, importers } = getModuleInfo(moduleId)!; + if (isEntry || dynamicImporters.length > 0) + dependentEntryPoints.push(moduleId); + + // The Set iterator is intelligent enough to iterate over + // elements that are added during iteration + for (const importerId of importers) idsToHandle.add(importerId); + } + + // If there is a unique entry, we put it into a chunk based on the + // entry name + if (dependentEntryPoints.length === 1) { + return `${key}.${ + dependentEntryPoints[0].split("/").slice(-1)[0].split(".")[0] + }.strings`; + } + // For multiple entries, we put it into a "shared" chunk + if (dependentEntryPoints.length > 1) { + return `${key}.shared.strings`; + } + } +}; + + +const manualChunks: GetManualChunk = (id, meta) => { + return chunkStrs(id, meta); +}; export default defineConfig(({ mode }) => ({ plugins: [ @@ -48,5 +92,10 @@ export default defineConfig(({ mode }) => ({ build: { target: ["firefox98", "safari15.4", "ios15.4", "chrome84", "edge87"], sourcemap: true, + rollupOptions: { + output: { + manualChunks, + }, + }, }, }));