Ver código fonte

refactor: use `unplugin-config` (#3110)

* refactor: use `unplugin-config`

* fix: preserve indentation in generated code

* refactor: use `unplugin-config`
Kirk Lin 1 ano atrás
pai
commit
e53fefb310

+ 1 - 0
internal/vite-config/package.json

@@ -48,6 +48,7 @@
     "rollup-plugin-visualizer": "^5.9.2",
     "sass": "^1.63.6",
     "unocss": "^0.53.4",
+    "unplugin-config": "^0.0.13",
     "vite-plugin-compression": "^0.5.1",
     "vite-plugin-dts": "^3.1.0",
     "vite-plugin-html": "^3.2.0",

+ 17 - 97
internal/vite-config/src/plugins/appConfig.ts

@@ -1,104 +1,24 @@
-import colors from 'picocolors';
-import { readPackageJSON } from 'pkg-types';
+import GenerateConfig from 'unplugin-config/vite';
 import { type PluginOption } from 'vite';
 
 import { getEnvConfig } from '../utils/env';
-import { createContentHash } from '../utils/hash';
+import { strToHex } from '../utils/hash';
 
 const GLOBAL_CONFIG_FILE_NAME = '_app.config.js';
-const PLUGIN_NAME = 'app-config';
-
-async function createAppConfigPlugin({
-  root,
-  isBuild,
-}: {
-  root: string;
-  isBuild: boolean;
-}): Promise<PluginOption> {
-  let publicPath: string;
-  let source: string;
-  if (!isBuild) {
-    return {
-      name: PLUGIN_NAME,
-    };
-  }
-  const { version = '' } = await readPackageJSON(root);
-
-  return {
-    name: PLUGIN_NAME,
-    async configResolved(_config) {
-      const appTitle = _config?.env?.VITE_GLOB_APP_TITLE ?? '';
-      // appTitle = appTitle.replace(/\s/g, '_').replace(/-/g, '_');
-      publicPath = _config.base;
-      source = await getConfigSource(appTitle);
-    },
-    async transformIndexHtml(html) {
-      publicPath = publicPath.endsWith('/') ? publicPath : `${publicPath}/`;
-
-      const appConfigSrc = `${
-        publicPath || '/'
-      }${GLOBAL_CONFIG_FILE_NAME}?v=${version}-${createContentHash(source)}`;
-
-      return {
-        html,
-        tags: [
-          {
-            tag: 'script',
-            attrs: {
-              src: appConfigSrc,
-            },
-          },
-        ],
-      };
-    },
-    async generateBundle() {
-      try {
-        this.emitFile({
-          type: 'asset',
-          fileName: GLOBAL_CONFIG_FILE_NAME,
-          source,
-        });
-
-        console.log(colors.cyan(`✨configuration file is build successfully!`));
-      } catch (error) {
-        console.log(
-          colors.red('configuration file configuration file failed to package:\n' + error),
-        );
-      }
-    },
-  };
-}
-
-/**
- * Get the configuration file variable name
- * @param env
- */
-const getVariableName = (title: string) => {
-  function strToHex(str: string) {
-    const result: string[] = [];
-    for (let i = 0; i < str.length; ++i) {
-      const hex = str.charCodeAt(i).toString(16);
-      result.push(('000' + hex).slice(-4));
-    }
-    return result.join('').toUpperCase();
-  }
-  return `__PRODUCTION__${strToHex(title) || '__APP'}__CONF__`.toUpperCase().replace(/\s/g, '');
-};
-
-async function getConfigSource(appTitle: string) {
+// This constant sets the output directory for the Vite package
+const OUTPUT_DIR = 'dist';
+export async function createConfigPluginConfig(
+  shouldGenerateConfig: boolean,
+): Promise<PluginOption> {
   const config = await getEnvConfig();
-  const variableName = getVariableName(appTitle);
-  const windowVariable = `window.${variableName}`;
-  // Ensure that the variable will not be modified
-  let source = `${windowVariable}=${JSON.stringify(config)};`;
-  source += `
-    Object.freeze(${windowVariable});
-    Object.defineProperty(window, "${variableName}", {
-      configurable: false,
-      writable: false,
-    });
-  `.replace(/\s/g, '');
-  return source;
+  // LINK /src/utils/env.ts -> getVariableName
+  const APP_NAME = strToHex(config?.VITE_GLOB_APP_TITLE ?? '__APP');
+  // https://github.com/kirklin/unplugin-config
+  return GenerateConfig({
+    disabledConfig: !shouldGenerateConfig,
+    globConfigFileName: GLOBAL_CONFIG_FILE_NAME,
+    outputDir: OUTPUT_DIR,
+    appName: APP_NAME,
+    envConfigPrefix: 'VITE_GLOB_',
+  });
 }
-
-export { createAppConfigPlugin };

+ 3 - 3
internal/vite-config/src/plugins/index.ts

@@ -3,7 +3,7 @@ import vueJsx from '@vitejs/plugin-vue-jsx';
 import { type PluginOption } from 'vite';
 import purgeIcons from 'vite-plugin-purge-icons';
 
-import { createAppConfigPlugin } from './appConfig';
+import { createConfigPluginConfig } from './appConfig';
 import { configCompressPlugin } from './compress';
 import { configHtmlPlugin } from './html';
 import { configMockPlugin } from './mock';
@@ -18,10 +18,10 @@ interface Options {
   enableAnalyze?: boolean;
 }
 
-async function createPlugins({ isBuild, root, enableMock, compress, enableAnalyze }: Options) {
+async function createPlugins({ isBuild, enableMock, compress, enableAnalyze }: Options) {
   const vitePlugins: (PluginOption | PluginOption[])[] = [vue(), vueJsx()];
 
-  const appConfigPlugin = await createAppConfigPlugin({ root, isBuild });
+  const appConfigPlugin = await createConfigPluginConfig(isBuild);
   vitePlugins.push(appConfigPlugin);
 
   // vite-plugin-html

+ 9 - 1
internal/vite-config/src/utils/hash.ts

@@ -4,5 +4,13 @@ function createContentHash(content: string, hashLSize = 12) {
   const hash = createHash('sha256').update(content);
   return hash.digest('hex').slice(0, hashLSize);
 }
+function strToHex(str: string) {
+  const result: string[] = [];
+  for (let i = 0; i < str.length; ++i) {
+    const hex = str.charCodeAt(i).toString(16);
+    result.push(('000' + hex).slice(-4));
+  }
+  return result.join('').toUpperCase();
+}
 
-export { createContentHash };
+export { createContentHash, strToHex };

+ 54 - 0
pnpm-lock.yaml

@@ -434,6 +434,9 @@ importers:
       unocss:
         specifier: ^0.53.4
         version: 0.53.4(postcss@8.4.24)(rollup@2.79.1)(vite@4.4.0)
+      unplugin-config:
+        specifier: ^0.0.13
+        version: 0.0.13(rollup@2.79.1)(vite@4.4.0)
       vite-plugin-compression:
         specifier: ^0.5.1
         version: 0.5.1(vite@4.4.0)
@@ -1939,6 +1942,10 @@ packages:
       '@jridgewell/resolve-uri': 3.1.1
       '@jridgewell/sourcemap-codec': 1.4.15
 
+  /@kirklin/logger@0.0.2:
+    resolution: {integrity: sha512-CGZ9HGmHGTcGnU8CDQm7RR7hZgxLyRHTIFpS1FDCQkVaipdL/poq72ibpKqqQflomgKRCYV6GReP7ZXEZeDx1w==}
+    dev: true
+
   /@logicflow/core@1.2.9:
     resolution: {integrity: sha512-3He1BXLYB+5bzgl28hZ24akLebPBGbnmNSvmKWZZdKn9jHVvqPbE3Yt3XEKzwTwSP92yPnGtkzx2FOOEgXa0iQ==}
     dependencies:
@@ -11300,6 +11307,44 @@ packages:
     resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==}
     engines: {node: '>= 0.8'}
 
+  /unplugin-config@0.0.13(rollup@2.79.1)(vite@4.4.0):
+    resolution: {integrity: sha512-VZyYzjzhNgXl/K7XrJshHZ0unex0vMH98KFtBckqiGUhxhY0yavQjGsA5sOAQgkuiFEJ+ZwdOdaQPwhMlrEfbg==}
+    peerDependencies:
+      '@nuxt/kit': ^3
+      '@nuxt/schema': ^3
+      esbuild: '*'
+      rollup: ^3
+      vite: '>=3'
+      webpack: ^4 || ^5
+    peerDependenciesMeta:
+      '@nuxt/kit':
+        optional: true
+      '@nuxt/schema':
+        optional: true
+      esbuild:
+        optional: true
+      rollup:
+        optional: true
+      vite:
+        optional: true
+      webpack:
+        optional: true
+    dependencies:
+      '@kirklin/logger': 0.0.2
+      rollup: 2.79.1
+      unplugin: 1.5.0
+      vite: 4.4.0(@types/node@20.4.0)(less@4.1.3)(sass@1.63.6)
+    dev: true
+
+  /unplugin@1.5.0:
+    resolution: {integrity: sha512-9ZdRwbh/4gcm1JTOkp9lAkIDrtOyOxgHmY7cjuwI8L/2RTikMcVG25GsZwNAgRuap3iDw2jeq7eoqtAsz5rW3A==}
+    dependencies:
+      acorn: 8.10.0
+      chokidar: 3.5.3
+      webpack-sources: 3.2.3
+      webpack-virtual-modules: 0.5.0
+    dev: true
+
   /unset-value@1.0.0:
     resolution: {integrity: sha512-PcA2tsuGSF9cnySLHTLSh2qrQiJ70mn+r+Glzxv2TWZblxsxCC52BDlZoPCsz7STd9pN7EZetkWZBAvk4cgZdQ==}
     engines: {node: '>=0.10.0'}
@@ -11790,6 +11835,15 @@ packages:
     engines: {node: '>=10.4'}
     dev: false
 
+  /webpack-sources@3.2.3:
+    resolution: {integrity: sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==}
+    engines: {node: '>=10.13.0'}
+    dev: true
+
+  /webpack-virtual-modules@0.5.0:
+    resolution: {integrity: sha512-kyDivFZ7ZM0BVOUteVbDFhlRt7Ah/CSPwJdi8hBpkK7QLumUqdLtVfm/PX/hkcnrvr0i77fO5+TjZ94Pe+C9iw==}
+    dev: true
+
   /whatwg-encoding@1.0.5:
     resolution: {integrity: sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==}
     dependencies: