@igstack/app-catalog-frontend-build-vite 6.1.2 → 6.1.3-alpha-20260925194417

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -39,5 +39,12 @@ export declare function frontendViteConfig(options?: {
39
39
  conditions: string[];
40
40
  };
41
41
  publicDir: string;
42
+ build: {
43
+ rollupOptions: {
44
+ output: {
45
+ manualChunks: (id: string) => string | undefined;
46
+ };
47
+ };
48
+ };
42
49
  plugins: import('vite').PluginOption[];
43
50
  };
@@ -144,6 +144,22 @@ function frontendViteConfig(options) {
144
144
  conditions: ["my-custom-condition"]
145
145
  },
146
146
  publicDir: ".vite-merged-public",
147
+ build: {
148
+ rollupOptions: {
149
+ output: {
150
+ // Stable vendor code gets its own chunks so their hashes — and the
151
+ // browser's cached copies — survive app-only deploys (#120).
152
+ manualChunks: (id) => {
153
+ var _a2;
154
+ const pkg = (_a2 = /[\\/]node_modules[\\/](react-dom|react|scheduler|@tanstack|@trpc)[\\/]/.exec(
155
+ id
156
+ )) == null ? void 0 : _a2[1];
157
+ if (!pkg) return void 0;
158
+ return pkg.startsWith("@") ? `vendor-${pkg.slice(1)}` : "vendor-react";
159
+ }
160
+ }
161
+ }
162
+ },
147
163
  plugins
148
164
  };
149
165
  }
@@ -1 +1 @@
1
- {"version":3,"file":"frontendViteConfig.js","sources":["../../src/frontendViteConfig.ts"],"sourcesContent":["import viteReact from '@vitejs/plugin-react'\nimport * as fs from 'node:fs'\nimport * as path from 'node:path'\nimport * as process from 'node:process'\nimport type { UserConfig } from 'vite'\nimport type { ManifestOptions } from 'vite-plugin-pwa'\nimport { VitePWA } from 'vite-plugin-pwa'\nimport { viteStaticCopy } from 'vite-plugin-static-copy'\nimport svgr from 'vite-plugin-svgr'\n\nexport function frontendViteConfig(options?: {\n appRoot?: string\n pwa?: {\n /**\n * Register VitePWA. Set `false` in a consumer that registers its own\n * VitePWA: two registrations both write `sw.js` and\n * `manifest.webmanifest`, and which precache manifest survives is decided\n * by plugin order.\n */\n enabled?: boolean\n manifest?: Partial<ManifestOptions>\n registerType?: 'autoUpdate' | 'prompt'\n selfDestroying?: boolean\n }\n}) {\n const plugins: UserConfig['plugins'] = []\n\n // Set up static copy for public assets if appRoot is provided\n if (options?.appRoot) {\n const appPublicDir = path.join(options.appRoot, 'public')\n\n // Copy core public assets first, then local public assets (local takes precedence)\n plugins.push(\n viteStaticCopy({\n targets: [\n {\n src: 'node_modules/@igstack/app-catalog-frontend-core/public/[!.]*',\n dest: '.',\n },\n ...(fs.existsSync(appPublicDir)\n ? [\n {\n src: 'public/[!.]*',\n dest: '.',\n },\n ]\n : []),\n ],\n }),\n )\n }\n\n // A consumer that registers its own VitePWA passes `pwa.enabled: false`:\n // two registrations write sw.js and manifest.webmanifest twice, and plugin\n // order decides which precache manifest survives.\n if (options?.pwa?.enabled !== false) {\n const registerType =\n options?.pwa?.registerType ||\n (process.env['VITE_AUTO_UPDATE'] === 'true' ? 'autoUpdate' : 'prompt')\n\n const selfDestroying =\n options?.pwa?.selfDestroying !== undefined\n ? options.pwa.selfDestroying\n : process.env['VITE_SELF_DESTROYING'] === 'true'\n ? true\n : undefined\n\n plugins.push(\n VitePWA({\n registerType,\n selfDestroying,\n workbox: {\n globPatterns: ['**/*.{js,css,html,ico,png,svg}'],\n },\n includeAssets: [\n 'favicon.ico',\n 'apple-touch-180x180.png',\n 'app-catalog-*.png',\n 'app-catalog-square.svg',\n ],\n manifest: {\n name: 'App Catalog',\n short_name: 'AC',\n description: 'Application catalog and directory',\n theme_color: '#1f2937',\n background_color: '#ffffff',\n display: 'standalone',\n start_url: '/',\n icons: [\n {\n src: 'favicon.ico',\n sizes: '48x48',\n type: 'image/x-icon',\n },\n {\n src: 'app-catalog-16x16.png',\n sizes: '16x16',\n type: 'image/png',\n },\n {\n src: 'app-catalog-32x32.png',\n sizes: '32x32',\n type: 'image/png',\n },\n {\n src: 'app-catalog-48x48.png',\n sizes: '48x48',\n type: 'image/png',\n },\n {\n src: 'app-catalog-192x192.png',\n sizes: '192x192',\n type: 'image/png',\n },\n {\n src: 'app-catalog-512x512.png',\n sizes: '512x512',\n type: 'image/png',\n },\n {\n src: 'app-catalog-square.svg',\n sizes: '150x150',\n type: 'image/svg+xml',\n },\n {\n src: 'app-catalog-square.svg',\n sizes: '150x150',\n purpose: 'maskable',\n type: 'image/svg+xml',\n },\n ],\n ...options?.pwa?.manifest,\n },\n devOptions: {\n enabled: true,\n },\n }),\n )\n }\n\n plugins.push(svgr())\n plugins.push(viteReact())\n\n if (process.env['NODE_ENV'] === 'test') {\n plugins.push({\n name: 'load-svg',\n enforce: 'pre',\n transform(_: string, id: string) {\n if (id.endsWith('.svg?react')) {\n return `export default () => \"svg-stub\"`\n }\n return undefined\n },\n })\n }\n\n // plugins.push(tanstackRouter());\n\n return {\n server: {\n port: 4000,\n strictPort: true,\n host: 'localhost',\n proxy: {\n '/api': {\n target: 'http://localhost:4001',\n changeOrigin: true,\n cookieDomainRewrite: 'localhost',\n },\n '/trpc': {\n target: 'http://localhost:4001',\n changeOrigin: true,\n cookieDomainRewrite: 'localhost',\n },\n '/static': {\n target: 'http://localhost:4001',\n changeOrigin: true,\n },\n },\n },\n resolve: {\n // Use 'my-custom-condition' to resolve @igstack/app-catalog-frontend-core to source files\n // This enables HMR when developing the core library alongside the consuming app\n conditions: ['my-custom-condition'],\n },\n publicDir: '.vite-merged-public',\n plugins,\n } satisfies UserConfig\n}\n"],"names":["path"],"mappings":"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"}
1
+ {"version":3,"file":"frontendViteConfig.js","sources":["../../src/frontendViteConfig.ts"],"sourcesContent":["import viteReact from '@vitejs/plugin-react'\nimport * as fs from 'node:fs'\nimport * as path from 'node:path'\nimport * as process from 'node:process'\nimport type { UserConfig } from 'vite'\nimport type { ManifestOptions } from 'vite-plugin-pwa'\nimport { VitePWA } from 'vite-plugin-pwa'\nimport { viteStaticCopy } from 'vite-plugin-static-copy'\nimport svgr from 'vite-plugin-svgr'\n\nexport function frontendViteConfig(options?: {\n appRoot?: string\n pwa?: {\n /**\n * Register VitePWA. Set `false` in a consumer that registers its own\n * VitePWA: two registrations both write `sw.js` and\n * `manifest.webmanifest`, and which precache manifest survives is decided\n * by plugin order.\n */\n enabled?: boolean\n manifest?: Partial<ManifestOptions>\n registerType?: 'autoUpdate' | 'prompt'\n selfDestroying?: boolean\n }\n}) {\n const plugins: UserConfig['plugins'] = []\n\n // Set up static copy for public assets if appRoot is provided\n if (options?.appRoot) {\n const appPublicDir = path.join(options.appRoot, 'public')\n\n // Copy core public assets first, then local public assets (local takes precedence)\n plugins.push(\n viteStaticCopy({\n targets: [\n {\n src: 'node_modules/@igstack/app-catalog-frontend-core/public/[!.]*',\n dest: '.',\n },\n ...(fs.existsSync(appPublicDir)\n ? [\n {\n src: 'public/[!.]*',\n dest: '.',\n },\n ]\n : []),\n ],\n }),\n )\n }\n\n // A consumer that registers its own VitePWA passes `pwa.enabled: false`:\n // two registrations write sw.js and manifest.webmanifest twice, and plugin\n // order decides which precache manifest survives.\n if (options?.pwa?.enabled !== false) {\n const registerType =\n options?.pwa?.registerType ||\n (process.env['VITE_AUTO_UPDATE'] === 'true' ? 'autoUpdate' : 'prompt')\n\n const selfDestroying =\n options?.pwa?.selfDestroying !== undefined\n ? options.pwa.selfDestroying\n : process.env['VITE_SELF_DESTROYING'] === 'true'\n ? true\n : undefined\n\n plugins.push(\n VitePWA({\n registerType,\n selfDestroying,\n workbox: {\n globPatterns: ['**/*.{js,css,html,ico,png,svg}'],\n },\n includeAssets: [\n 'favicon.ico',\n 'apple-touch-180x180.png',\n 'app-catalog-*.png',\n 'app-catalog-square.svg',\n ],\n manifest: {\n name: 'App Catalog',\n short_name: 'AC',\n description: 'Application catalog and directory',\n theme_color: '#1f2937',\n background_color: '#ffffff',\n display: 'standalone',\n start_url: '/',\n icons: [\n {\n src: 'favicon.ico',\n sizes: '48x48',\n type: 'image/x-icon',\n },\n {\n src: 'app-catalog-16x16.png',\n sizes: '16x16',\n type: 'image/png',\n },\n {\n src: 'app-catalog-32x32.png',\n sizes: '32x32',\n type: 'image/png',\n },\n {\n src: 'app-catalog-48x48.png',\n sizes: '48x48',\n type: 'image/png',\n },\n {\n src: 'app-catalog-192x192.png',\n sizes: '192x192',\n type: 'image/png',\n },\n {\n src: 'app-catalog-512x512.png',\n sizes: '512x512',\n type: 'image/png',\n },\n {\n src: 'app-catalog-square.svg',\n sizes: '150x150',\n type: 'image/svg+xml',\n },\n {\n src: 'app-catalog-square.svg',\n sizes: '150x150',\n purpose: 'maskable',\n type: 'image/svg+xml',\n },\n ],\n ...options?.pwa?.manifest,\n },\n devOptions: {\n enabled: true,\n },\n }),\n )\n }\n\n plugins.push(svgr())\n plugins.push(viteReact())\n\n if (process.env['NODE_ENV'] === 'test') {\n plugins.push({\n name: 'load-svg',\n enforce: 'pre',\n transform(_: string, id: string) {\n if (id.endsWith('.svg?react')) {\n return `export default () => \"svg-stub\"`\n }\n return undefined\n },\n })\n }\n\n // plugins.push(tanstackRouter());\n\n return {\n server: {\n port: 4000,\n strictPort: true,\n host: 'localhost',\n proxy: {\n '/api': {\n target: 'http://localhost:4001',\n changeOrigin: true,\n cookieDomainRewrite: 'localhost',\n },\n '/trpc': {\n target: 'http://localhost:4001',\n changeOrigin: true,\n cookieDomainRewrite: 'localhost',\n },\n '/static': {\n target: 'http://localhost:4001',\n changeOrigin: true,\n },\n },\n },\n resolve: {\n // Use 'my-custom-condition' to resolve @igstack/app-catalog-frontend-core to source files\n // This enables HMR when developing the core library alongside the consuming app\n conditions: ['my-custom-condition'],\n },\n publicDir: '.vite-merged-public',\n build: {\n rollupOptions: {\n output: {\n // Stable vendor code gets its own chunks so their hashes — and the\n // browser's cached copies — survive app-only deploys (#120).\n manualChunks: (id: string) => {\n const pkg =\n /[\\\\/]node_modules[\\\\/](react-dom|react|scheduler|@tanstack|@trpc)[\\\\/]/.exec(\n id,\n )?.[1]\n if (!pkg) return undefined\n return pkg.startsWith('@')\n ? `vendor-${pkg.slice(1)}`\n : 'vendor-react'\n },\n },\n },\n },\n plugins,\n } satisfies UserConfig\n}\n"],"names":["path","_a"],"mappings":";;;;;;;AAUO,SAAS,mBAAmB,SAchC;;AACD,QAAM,UAAiC,CAAA;AAGvC,MAAI,mCAAS,SAAS;AACpB,UAAM,eAAeA,GAAK,KAAK,QAAQ,SAAS,QAAQ;AAGxD,YAAQ;AAAA,MACN,eAAe;AAAA,QACb,SAAS;AAAA,UACP;AAAA,YACE,KAAK;AAAA,YACL,MAAM;AAAA,UAAA;AAAA,UAER,GAAI,GAAG,WAAW,YAAY,IAC1B;AAAA,YACE;AAAA,cACE,KAAK;AAAA,cACL,MAAM;AAAA,YAAA;AAAA,UACR,IAEF,CAAA;AAAA,QAAC;AAAA,MACP,CACD;AAAA,IAAA;AAAA,EAEL;AAKA,QAAI,wCAAS,QAAT,mBAAc,aAAY,OAAO;AACnC,UAAM,iBACJ,wCAAS,QAAT,mBAAc,kBACb,QAAQ,IAAI,kBAAkB,MAAM,SAAS,eAAe;AAE/D,UAAM,mBACJ,wCAAS,QAAT,mBAAc,oBAAmB,SAC7B,QAAQ,IAAI,iBACZ,QAAQ,IAAI,sBAAsB,MAAM,SACtC,OACA;AAER,YAAQ;AAAA,MACN,QAAQ;AAAA,QACN;AAAA,QACA;AAAA,QACA,SAAS;AAAA,UACP,cAAc,CAAC,gCAAgC;AAAA,QAAA;AAAA,QAEjD,eAAe;AAAA,UACb;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QAAA;AAAA,QAEF,UAAU;AAAA,UACR,MAAM;AAAA,UACN,YAAY;AAAA,UACZ,aAAa;AAAA,UACb,aAAa;AAAA,UACb,kBAAkB;AAAA,UAClB,SAAS;AAAA,UACT,WAAW;AAAA,UACX,OAAO;AAAA,YACL;AAAA,cACE,KAAK;AAAA,cACL,OAAO;AAAA,cACP,MAAM;AAAA,YAAA;AAAA,YAER;AAAA,cACE,KAAK;AAAA,cACL,OAAO;AAAA,cACP,MAAM;AAAA,YAAA;AAAA,YAER;AAAA,cACE,KAAK;AAAA,cACL,OAAO;AAAA,cACP,MAAM;AAAA,YAAA;AAAA,YAER;AAAA,cACE,KAAK;AAAA,cACL,OAAO;AAAA,cACP,MAAM;AAAA,YAAA;AAAA,YAER;AAAA,cACE,KAAK;AAAA,cACL,OAAO;AAAA,cACP,MAAM;AAAA,YAAA;AAAA,YAER;AAAA,cACE,KAAK;AAAA,cACL,OAAO;AAAA,cACP,MAAM;AAAA,YAAA;AAAA,YAER;AAAA,cACE,KAAK;AAAA,cACL,OAAO;AAAA,cACP,MAAM;AAAA,YAAA;AAAA,YAER;AAAA,cACE,KAAK;AAAA,cACL,OAAO;AAAA,cACP,SAAS;AAAA,cACT,MAAM;AAAA,YAAA;AAAA,UACR;AAAA,UAEF,IAAG,wCAAS,QAAT,mBAAc;AAAA,QAAA;AAAA,QAEnB,YAAY;AAAA,UACV,SAAS;AAAA,QAAA;AAAA,MACX,CACD;AAAA,IAAA;AAAA,EAEL;AAEA,UAAQ,KAAK,MAAM;AACnB,UAAQ,KAAK,WAAW;AAExB,MAAI,QAAQ,IAAI,UAAU,MAAM,QAAQ;AACtC,YAAQ,KAAK;AAAA,MACX,MAAM;AAAA,MACN,SAAS;AAAA,MACT,UAAU,GAAW,IAAY;AAC/B,YAAI,GAAG,SAAS,YAAY,GAAG;AAC7B,iBAAO;AAAA,QACT;AACA,eAAO;AAAA,MACT;AAAA,IAAA,CACD;AAAA,EACH;AAIA,SAAO;AAAA,IACL,QAAQ;AAAA,MACN,MAAM;AAAA,MACN,YAAY;AAAA,MACZ,MAAM;AAAA,MACN,OAAO;AAAA,QACL,QAAQ;AAAA,UACN,QAAQ;AAAA,UACR,cAAc;AAAA,UACd,qBAAqB;AAAA,QAAA;AAAA,QAEvB,SAAS;AAAA,UACP,QAAQ;AAAA,UACR,cAAc;AAAA,UACd,qBAAqB;AAAA,QAAA;AAAA,QAEvB,WAAW;AAAA,UACT,QAAQ;AAAA,UACR,cAAc;AAAA,QAAA;AAAA,MAChB;AAAA,IACF;AAAA,IAEF,SAAS;AAAA;AAAA;AAAA,MAGP,YAAY,CAAC,qBAAqB;AAAA,IAAA;AAAA,IAEpC,WAAW;AAAA,IACX,OAAO;AAAA,MACL,eAAe;AAAA,QACb,QAAQ;AAAA;AAAA;AAAA,UAGN,cAAc,CAAC,OAAe;;AAC5B,kBAAM,OACJC,MAAA,yEAAyE;AAAA,cACvE;AAAA,YAAA,MADF,gBAAAA,IAEI;AACN,gBAAI,CAAC,IAAK,QAAO;AACjB,mBAAO,IAAI,WAAW,GAAG,IACrB,UAAU,IAAI,MAAM,CAAC,CAAC,KACtB;AAAA,UACN;AAAA,QAAA;AAAA,MACF;AAAA,IACF;AAAA,IAEF;AAAA,EAAA;AAEJ;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@igstack/app-catalog-frontend-build-vite",
3
- "version": "6.1.2",
3
+ "version": "6.1.3-alpha-20260925194417",
4
4
  "description": "Vite build config for App Catalog frontend",
5
5
  "homepage": "https://github.com/lislon/app-catalog",
6
6
  "repository": {
@@ -45,7 +45,7 @@
45
45
  "tsx": "^4.19.4",
46
46
  "typescript": "5.9.3",
47
47
  "vite": "^6.3.5",
48
- "@igstack/app-catalog-shared-core": "6.1.2"
48
+ "@igstack/app-catalog-shared-core": "6.1.3-alpha-20260925194417"
49
49
  },
50
50
  "peerDependencies": {
51
51
  "vite": "^6.3.5",
@@ -54,7 +54,7 @@
54
54
  "engines": {
55
55
  "node": ">=16"
56
56
  },
57
- "gitHead": "4a1563a8af22aee2d0ae77c471bffe6253db57f3",
57
+ "gitHead": "aa30fb950f715ba9734b220e338bbef24c8bcc79",
58
58
  "scripts": {
59
59
  "build": "vite build",
60
60
  "build:lenient": "vite build --mode lenient",
@@ -184,6 +184,24 @@ export function frontendViteConfig(options?: {
184
184
  conditions: ['my-custom-condition'],
185
185
  },
186
186
  publicDir: '.vite-merged-public',
187
+ build: {
188
+ rollupOptions: {
189
+ output: {
190
+ // Stable vendor code gets its own chunks so their hashes — and the
191
+ // browser's cached copies — survive app-only deploys (#120).
192
+ manualChunks: (id: string) => {
193
+ const pkg =
194
+ /[\\/]node_modules[\\/](react-dom|react|scheduler|@tanstack|@trpc)[\\/]/.exec(
195
+ id,
196
+ )?.[1]
197
+ if (!pkg) return undefined
198
+ return pkg.startsWith('@')
199
+ ? `vendor-${pkg.slice(1)}`
200
+ : 'vendor-react'
201
+ },
202
+ },
203
+ },
204
+ },
187
205
  plugins,
188
206
  } satisfies UserConfig
189
207
  }