From 772b2f73b0da08181a7cc29e0eb50073ff3cc464 Mon Sep 17 00:00:00 2001 From: Etienne Date: Wed, 14 Jul 2021 16:11:28 +0200 Subject: [PATCH] feat: enable usage of function as library fileName, close #3585 (#3625) --- docs/config/index.md | 4 +-- docs/guide/build.md | 3 +- packages/playground/lib/index.dist.html | 5 ++- packages/playground/lib/vite.config.js | 3 +- .../vite/src/node/__tests__/build.spec.ts | 32 +++++++++++++++++++ packages/vite/src/node/build.ts | 17 ++++++++-- 6 files changed, 54 insertions(+), 10 deletions(-) create mode 100644 packages/vite/src/node/__tests__/build.spec.ts diff --git a/docs/config/index.md b/docs/config/index.md index 716fd069b6424a..e333c277635e9a 100644 --- a/docs/config/index.md +++ b/docs/config/index.md @@ -621,10 +621,10 @@ createServer() ### build.lib -- **Type:** `{ entry: string, name?: string, formats?: ('es' | 'cjs' | 'umd' | 'iife')[], fileName?: string }` +- **Type:** `{ entry: string, name?: string, formats?: ('es' | 'cjs' | 'umd' | 'iife')[], fileName?: string | ((format: ModuleFormat) => string) }` - **Related:** [Library Mode](/guide/build#library-mode) - Build as a library. `entry` is required since the library cannot use HTML as entry. `name` is the exposed global variable and is required when `formats` includes `'umd'` or `'iife'`. Default `formats` are `['es', 'umd']`. `fileName` is the name of the package file output, default `fileName` is the name option of package.json + Build as a library. `entry` is required since the library cannot use HTML as entry. `name` is the exposed global variable and is required when `formats` includes `'umd'` or `'iife'`. Default `formats` are `['es', 'umd']`. `fileName` is the name of the package file output, default `fileName` is the name option of package.json, it can also be defined as function taking the `format` as an argument. ### build.manifest diff --git a/docs/guide/build.md b/docs/guide/build.md index e2e18b2f5b5798..d45fe5a24168e8 100644 --- a/docs/guide/build.md +++ b/docs/guide/build.md @@ -108,7 +108,8 @@ module.exports = { build: { lib: { entry: path.resolve(__dirname, 'lib/main.js'), - name: 'MyLib' + name: 'MyLib', + fileName: format => `my-lib.${format}.js` }, rollupOptions: { // make sure to externalize deps that shouldn't be bundled diff --git a/packages/playground/lib/index.dist.html b/packages/playground/lib/index.dist.html index 3416c1f3952fa9..eddf3006a66aec 100644 --- a/packages/playground/lib/index.dist.html +++ b/packages/playground/lib/index.dist.html @@ -1,15 +1,14 @@ -
- + diff --git a/packages/playground/lib/vite.config.js b/packages/playground/lib/vite.config.js index a80800f6ad3d58..2545d488e165ad 100644 --- a/packages/playground/lib/vite.config.js +++ b/packages/playground/lib/vite.config.js @@ -8,7 +8,8 @@ module.exports = { build: { lib: { entry: path.resolve(__dirname, 'src/main.js'), - name: 'MyLib' + name: 'MyLib', + fileName: (format) => `my-lib-custom-filename.${format}.js` } }, plugins: [ diff --git a/packages/vite/src/node/__tests__/build.spec.ts b/packages/vite/src/node/__tests__/build.spec.ts new file mode 100644 index 00000000000000..15bca18c91bfc4 --- /dev/null +++ b/packages/vite/src/node/__tests__/build.spec.ts @@ -0,0 +1,32 @@ +import { resolveLibFilename } from '../build' + +describe('resolveLibFilename', () => { + test('custom filename function', () => { + const filename = resolveLibFilename( + { + fileName: (format) => `custom-filename-function.${format}.js`, + entry: 'mylib.js' + }, + 'es', + 'mylib' + ) + + expect(filename).toBe('custom-filename-function.es.js') + }) + + test('custom filename string', () => { + const filename = resolveLibFilename( + { fileName: 'custom-filename', entry: 'mylib.js' }, + 'es', + 'mylib' + ) + + expect(filename).toBe('custom-filename.es.js') + }) + + test('package name as filename', () => { + const filename = resolveLibFilename({ entry: 'mylib.js' }, 'es', 'mylib') + + expect(filename).toBe('mylib.es.js') + }) +}) diff --git a/packages/vite/src/node/build.ts b/packages/vite/src/node/build.ts index c39ef603fa861e..f19192c0bc0404 100644 --- a/packages/vite/src/node/build.ts +++ b/packages/vite/src/node/build.ts @@ -15,7 +15,8 @@ import Rollup, { GetModuleInfo, WatcherOptions, RollupWatcher, - RollupError + RollupError, + ModuleFormat } from 'rollup' import { buildReporterPlugin } from './plugins/reporter' import { buildHtmlPlugin } from './plugins/html' @@ -198,7 +199,7 @@ export interface LibraryOptions { entry: string name?: string formats?: LibraryFormats[] - fileName?: string + fileName?: string | ((format: ModuleFormat) => string) } export type LibraryFormats = 'es' | 'cjs' | 'umd' | 'iife' @@ -425,7 +426,7 @@ async function doBuild( entryFileNames: ssr ? `[name].js` : libOptions - ? `${libOptions.fileName || pkgName}.${output.format || `es`}.js` + ? resolveLibFilename(libOptions, output.format || 'es', pkgName) : path.posix.join(options.assetsDir, `[name].[hash].js`), chunkFileNames: libOptions ? `[name].js` @@ -621,6 +622,16 @@ function staticImportedByEntry( return someImporterIs } +export function resolveLibFilename( + libOptions: LibraryOptions, + format: ModuleFormat, + pkgName: string +): string { + return typeof libOptions.fileName === 'function' + ? libOptions.fileName(format) + : `${libOptions.fileName || pkgName}.${format}.js` +} + function resolveBuildOutputs( outputs: OutputOptions | OutputOptions[] | undefined, libOptions: LibraryOptions | false,