From b28314805783265c561eb5cfde55bce1cc5332e3 Mon Sep 17 00:00:00 2001 From: Cynthia Date: Sat, 6 Jul 2024 11:58:26 +0200 Subject: [PATCH 1/2] build: improve support for code splitting, ditch umd, sourcemaps --- packages/radix-vue/package.json | 6 +++--- packages/radix-vue/vite.config.ts | 29 ++++++++++++++--------------- 2 files changed, 17 insertions(+), 18 deletions(-) diff --git a/packages/radix-vue/package.json b/packages/radix-vue/package.json index d95ccfc21..f64dcb2b4 100644 --- a/packages/radix-vue/package.json +++ b/packages/radix-vue/package.json @@ -29,7 +29,7 @@ ".": { "types": "./dist/index.d.ts", "import": "./dist/index.js", - "require": "./dist/index.umd.cjs" + "require": "./dist/index.cjs" }, "./date": { "import": { @@ -38,7 +38,7 @@ }, "require": { "types": "./dist/date/index.d.ts", - "default": "./dist/date.umd.cjs" + "default": "./dist/date.cjs" } }, "./namespaced": { @@ -72,7 +72,7 @@ } } }, - "main": "./dist/index.umd.cjs", + "main": "./dist/index.cjs", "module": "./dist/index.js", "types": "./dist/index.d.ts", "typings": "./dist/index.d.ts", diff --git a/packages/radix-vue/vite.config.ts b/packages/radix-vue/vite.config.ts index 47070e41b..8c28fc11b 100644 --- a/packages/radix-vue/vite.config.ts +++ b/packages/radix-vue/vite.config.ts @@ -1,8 +1,9 @@ -import { resolve } from 'node:path' +import { relative, resolve } from 'node:path' import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' import vueJsx from '@vitejs/plugin-vue-jsx' import dts from 'vite-plugin-dts' +import pkg from './package.json' const projectRootDir = resolve(__dirname) @@ -13,8 +14,9 @@ export default defineConfig({ vueJsx(), dts({ tsconfigPath: 'tsconfig.build.json', - cleanVueFileName: true, exclude: ['src/test/**', 'src/**/story/**', 'src/**/*.story.vue'], + cleanVueFileName: true, + rollupTypes: true, }), ], resolve: { @@ -27,28 +29,25 @@ export default defineConfig({ ], }, build: { + target: 'esnext', + sourcemap: true, lib: { name: 'radix-vue', - fileName: (format, name) => { - return `${name}.${format === 'es' ? 'js' : 'umd.cjs'}` - }, + formats: ['es', 'cjs'], entry: { index: resolve(__dirname, 'src/index.ts'), date: resolve(__dirname, 'src/date/index.ts'), }, }, rollupOptions: { - // make sure to externalize deps that shouldn't be bundled - // into your library (Vue) - external: ['vue', '@floating-ui/vue', '@internationalized/date', '@internationalized/number'], + external: [ + 'nanoid/non-secure', + ...Object.keys(pkg.dependencies ?? {}), + ...Object.keys(pkg.peerDependencies ?? {}), + ], output: { - // Provide global variables to use in the UMD build - // for externalized deps - globals: { - 'vue': 'Vue', - '@floating-ui/vue': '@floating-ui/vue', - '@internationalized/date': '@internationalized/date', - '@internationalized/number': '@internationalized/number', + manualChunks: (moduleId) => { + return relative(projectRootDir, moduleId).split('/')[1] }, assetFileNames: (chunkInfo) => { if (chunkInfo.name === 'style.css') From 7aaa3efd1ea989efbd7def8c7cc2fb5176561a4d Mon Sep 17 00:00:00 2001 From: Cynthia Date: Tue, 9 Jul 2024 21:45:52 +0200 Subject: [PATCH 2/2] build: output minified cjs without maps --- packages/radix-vue/package.json | 4 +++- packages/radix-vue/vite.config.cjs.ts | 24 ++++++++++++++++++++++++ packages/radix-vue/vite.config.ts | 26 +++++++++++++++++++++++--- 3 files changed, 50 insertions(+), 4 deletions(-) create mode 100644 packages/radix-vue/vite.config.cjs.ts diff --git a/packages/radix-vue/package.json b/packages/radix-vue/package.json index f64dcb2b4..5f31306c3 100644 --- a/packages/radix-vue/package.json +++ b/packages/radix-vue/package.json @@ -82,7 +82,9 @@ ], "scripts": { "build": "pnpm type-check && pnpm build-only", - "build-only": "vite build", + "build-only": "pnpm run build-only-esm && pnpm run build-only-cjs", + "build-only-esm": "vite build", + "build-only-cjs": "vite build --config vite.config.cjs.ts", "watch": "vite build --watch", "type-check": "vue-tsc -p tsconfig.check.json --noEmit", "type-gen": "vue-tsc --declaration --emitDeclarationOnly", diff --git a/packages/radix-vue/vite.config.cjs.ts b/packages/radix-vue/vite.config.cjs.ts new file mode 100644 index 000000000..986186ddd --- /dev/null +++ b/packages/radix-vue/vite.config.cjs.ts @@ -0,0 +1,24 @@ +import { defineConfig, mergeConfig } from 'vite' +import viteConfig from './vite.config' + +const merged = defineConfig(mergeConfig(viteConfig, defineConfig({ + build: { + emptyOutDir: false, // Contains esm build + target: 'es2022', // Transpile syntax to Node 18+ + sourcemap: false, + minify: true, + rollupOptions: { + output: { + // No code splitting + manualChunks: {}, + }, + }, + }, +}))) + +// We need to *replace* these, however mergeConfig won't let us do that (it wants to merge the arrays). +merged.plugins = merged.plugins.slice(0, -1) // Don't run DTS +if (merged.build.lib) + merged.build.lib.formats = ['cjs'] + +export default merged diff --git a/packages/radix-vue/vite.config.ts b/packages/radix-vue/vite.config.ts index 8c28fc11b..ca1caf6a5 100644 --- a/packages/radix-vue/vite.config.ts +++ b/packages/radix-vue/vite.config.ts @@ -1,4 +1,4 @@ -import { relative, resolve } from 'node:path' +import { resolve } from 'node:path' import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' import vueJsx from '@vitejs/plugin-vue-jsx' @@ -33,7 +33,7 @@ export default defineConfig({ sourcemap: true, lib: { name: 'radix-vue', - formats: ['es', 'cjs'], + formats: ['es'], entry: { index: resolve(__dirname, 'src/index.ts'), date: resolve(__dirname, 'src/date/index.ts'), @@ -46,8 +46,28 @@ export default defineConfig({ ...Object.keys(pkg.peerDependencies ?? {}), ], output: { + // The package is split in chunks to make lazy-loading possible. + // No major bundler supports splitting files, even if the file itself is side effects free. + // + // Each namespace (Accordion, AlertDialog, ...) is bundled as individual chunks re-exported by index.js. + // This allows namespace-level granularity which is enough for all realistic code-splitting scenarios. + // + // The only exception are components intended for root-level usage, which are bundled in their own chunk. + // This allows setting up a component's provider while still lazy-loading the actual component. manualChunks: (moduleId) => { - return relative(projectRootDir, moduleId).split('/')[1] + const [namespace, file] = moduleId.split('?')[0].split('/').slice(-2) + + // Entrypoint + if (namespace === 'src') + return file + + // Providers + const ROOT_LEVEL_COMPONENTS = ['ToastProvider.vue', 'TooltipProvider.vue'] + if (ROOT_LEVEL_COMPONENTS.includes(file)) + return 'RootProviders' + + // Namespace + return namespace }, assetFileNames: (chunkInfo) => { if (chunkInfo.name === 'style.css')