diff --git a/.changeset/curvy-cougars-wonder.md b/.changeset/curvy-cougars-wonder.md new file mode 100644 index 0000000..0f9f962 --- /dev/null +++ b/.changeset/curvy-cougars-wonder.md @@ -0,0 +1,5 @@ +--- +'vite-plugin-static-copy': minor +--- + +Allows user to optionally configure when the plugin is ran by passing in a Rollup hook name diff --git a/src/build.ts b/src/build.ts index 15470f3..15afc9f 100644 --- a/src/build.ts +++ b/src/build.ts @@ -5,7 +5,8 @@ import { copyAll, outputCopyLog } from './utils' export const buildPlugin = ({ targets, structured, - silent + silent, + hook }: ResolvedViteStaticCopyOptions): Plugin => { let config: ResolvedConfig let output = false @@ -20,7 +21,7 @@ export const buildPlugin = ({ // reset for watch mode output = false }, - async writeBundle() { + async [hook]() { // run copy only once even if multiple bundles are generated if (output) return output = true diff --git a/src/options.ts b/src/options.ts index 22e3233..a994e74 100644 --- a/src/options.ts +++ b/src/options.ts @@ -105,6 +105,11 @@ export type ViteStaticCopyOptions = { */ reloadPageOnChange?: boolean } + /** + * Rollup hook the plugin should use during build. + * @default 'writeBundle' + */ + hook?: string } export type ResolvedViteStaticCopyOptions = { @@ -115,6 +120,7 @@ export type ResolvedViteStaticCopyOptions = { options: WatchOptions reloadPageOnChange: boolean } + hook: string } export const resolveOptions = ( @@ -126,5 +132,6 @@ export const resolveOptions = ( watch: { options: options.watch?.options ?? {}, reloadPageOnChange: options.watch?.reloadPageOnChange ?? false - } + }, + hook: options.hook ?? 'writeBundle' }) diff --git a/test/fixtures/vite.hook.config.ts b/test/fixtures/vite.hook.config.ts new file mode 100644 index 0000000..87202e0 --- /dev/null +++ b/test/fixtures/vite.hook.config.ts @@ -0,0 +1,34 @@ +import { defineConfig, normalizePath } from 'vite' +import { viteStaticCopy } from 'vite-plugin-static-copy' +import fs from 'node:fs/promises' +import path from 'node:path' +import url from 'node:url' + +const _dirname = path.dirname(url.fileURLToPath(import.meta.url)) + +export default defineConfig({ + plugins: [ + viteStaticCopy({ + targets: [ + { + src: 'foo.txt', + dest: 'hook1' + } + ], + hook: 'generateBundle' + }), + testHookPlugin() + ] +}) + +function testHookPlugin() { + return { + name: 'test-hook-plugin', + async writeBundle() { + const filePath = normalizePath( + path.resolve(_dirname, 'dist', 'hook1', 'foo.txt') + ) + await fs.access(filePath) + } + } +} diff --git a/test/tests.test.ts b/test/tests.test.ts index a64a985..183a792 100644 --- a/test/tests.test.ts +++ b/test/tests.test.ts @@ -137,6 +137,17 @@ describe('build', () => { } }) } + + test('should support hook option', async () => { + let result = '' + try { + await build(getConfig('vite.hook.config.ts')) + } catch (error: unknown) { + result = (error as Error).message + } + expect(result).toBe('') + }) + describe('on error', () => { test('should throw error when it does not find the file on given src', async () => { let result = ''