From 00418576672738f391ee8a78ba677d83b7ea1d99 Mon Sep 17 00:00:00 2001 From: Bruno Imbrizi Date: Tue, 30 May 2023 18:02:45 +0100 Subject: [PATCH 1/5] fix: trim slashes from dest when flatten false; add support to ../ --- src/utils.ts | 9 ++++----- test/testcases.ts | 2 +- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/utils.ts b/src/utils.ts index db1e260..3a8dc62 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -71,11 +71,10 @@ export const collectCopyTargets = async ( // https://github.com/vladshcherbin/rollup-plugin-copy/blob/507bf5e99aa2c6d0d858821e627cb7617a1d9a6d/src/index.js#L32-L35 const { base, dir } = path.parse(matchedPath) - const destDir = - flatten || (!flatten && !dir) - ? dest - : // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - dir.replace(dir.split('/')[0]!, dest) + + const dirClean = dir.replace(/^(?:\.\.\/)+/, '') + const destClean = `${dest}/${dirClean}`.replace(/^\/+|\/+$/g, '') + const destDir = flatten || (!flatten && !dir) ? dest : destClean copyTargets.push({ src: matchedPath, diff --git a/test/testcases.ts b/test/testcases.ts index 63a890d..21adae2 100644 --- a/test/testcases.ts +++ b/test/testcases.ts @@ -140,7 +140,7 @@ export const testcases: Record = { { name: 'glob with dir', src: './dir/bar.txt', - dest: '/fixture2/bar.txt' + dest: '/fixture2/dir/bar.txt' }, { name: 'glob with parent dir', From 86aa01d474f48f2808a8bd2abb45cc8648b0e8be Mon Sep 17 00:00:00 2001 From: Bruno Imbrizi Date: Wed, 31 May 2023 15:59:12 +0100 Subject: [PATCH 2/5] test: add empty dest tests --- test/fixtures/vite.noflatten.config.ts | 14 +++++++++++++- test/testcases.ts | 15 +++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/test/fixtures/vite.noflatten.config.ts b/test/fixtures/vite.noflatten.config.ts index 26b97c1..8c0bd67 100644 --- a/test/fixtures/vite.noflatten.config.ts +++ b/test/fixtures/vite.noflatten.config.ts @@ -19,7 +19,19 @@ export default defineConfig({ { src: '../fixtures2/*.txt', dest: 'fixture3' - } + }, + { + src: 'foo.js', + dest: '' + }, + { + src: 'noext', + dest: '.' + }, + { + src: '../fixtures2/baz.txt', + dest: '' + }, ], flatten: false }) diff --git a/test/testcases.ts b/test/testcases.ts index 21adae2..bccbcf5 100644 --- a/test/testcases.ts +++ b/test/testcases.ts @@ -146,6 +146,21 @@ export const testcases: Record = { name: 'glob with parent dir', src: '../fixtures2/baz.txt', dest: '/fixture3/fixtures2/baz.txt' + }, + { + name: 'empty dest', + src: './foo.js', + dest: '/foo.js' + }, + { + name: 'dot dest', + src: './noext', + dest: '/noext' + }, + { + name: 'parent dir to empty dest', + src: '../fixtures2/baz.txt', + dest: '/fixtures2/baz.txt' } ] } From e715abbf498485900e8dc1d53513a83eb3e722df Mon Sep 17 00:00:00 2001 From: Bruno Imbrizi Date: Wed, 31 May 2023 16:03:26 +0100 Subject: [PATCH 3/5] test: simplify tests --- test/fixtures/vite.noflatten.config.ts | 4 ++-- test/testcases.ts | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/test/fixtures/vite.noflatten.config.ts b/test/fixtures/vite.noflatten.config.ts index 8c0bd67..788312a 100644 --- a/test/fixtures/vite.noflatten.config.ts +++ b/test/fixtures/vite.noflatten.config.ts @@ -29,9 +29,9 @@ export default defineConfig({ dest: '.' }, { - src: '../fixtures2/baz.txt', + src: 'dir/bar.txt', dest: '' - }, + } ], flatten: false }) diff --git a/test/testcases.ts b/test/testcases.ts index bccbcf5..9a1e58b 100644 --- a/test/testcases.ts +++ b/test/testcases.ts @@ -158,9 +158,9 @@ export const testcases: Record = { dest: '/noext' }, { - name: 'parent dir to empty dest', - src: '../fixtures2/baz.txt', - dest: '/fixtures2/baz.txt' + name: 'dir to empty dest', + src: './dir/bar.txt', + dest: '/dir/bar.txt' } ] } From 7021c6569fa974d8435c98d1fdfed6e9a22d9d48 Mon Sep 17 00:00:00 2001 From: Bruno Imbrizi Date: Wed, 31 May 2023 16:36:31 +0100 Subject: [PATCH 4/5] feat: replace flatten: false with structured: true --- README.md | 1 + src/build.ts | 4 ++-- src/options.ts | 10 +++++----- src/serve.ts | 4 ++-- src/utils.ts | 8 ++++---- test/fixtures/package.json | 4 ++-- ...e.noflatten.config.ts => vite.structured.config.ts} | 4 ++-- test/testcases.ts | 2 +- 8 files changed, 19 insertions(+), 18 deletions(-) rename test/fixtures/{vite.noflatten.config.ts => vite.structured.config.ts} (92%) diff --git a/README.md b/README.md index 6fe11bb..02333af 100644 --- a/README.md +++ b/README.md @@ -70,3 +70,4 @@ See [options.ts](https://github.com/sapphi-red/vite-plugin-static-copy/blob/main - Because `fast-glob` is used inside `vite`. - `transform` could return `null` as a way to tell the plugin not to copy the file, this is similar to the [CopyWebpackPlugin#filter](https://webpack.js.org/plugins/copy-webpack-plugin/#filter) option, but it expects `transform` to return the original content in case you want it to be copied. - `transform` can optionally be an object, with a `handler` property (with the same signature of the `rollup-plugin-copy` transform option) and an `encoding` property (`BufferEncoding | 'buffer'`) that will be used to read the file content so that the `handler`'s content argument will reflect the correct encoding (could be Buffer); +- `structured: true` preserves the directory structure. It is similar to `flatten: false` in `rollup-plugin-copy`, but it covers more edge cases. diff --git a/src/build.ts b/src/build.ts index 750391b..81d1613 100644 --- a/src/build.ts +++ b/src/build.ts @@ -4,7 +4,7 @@ import { copyAll, outputCopyLog } from './utils' export const buildPlugin = ({ targets, - flatten, + structured, silent }: ResolvedViteStaticCopyOptions): Plugin => { let config: ResolvedConfig @@ -20,7 +20,7 @@ export const buildPlugin = ({ config.root, config.build.outDir, targets, - flatten + structured ) if (!silent) outputCopyLog(config.logger, result) } diff --git a/src/options.ts b/src/options.ts index e1ca584..11606c9 100644 --- a/src/options.ts +++ b/src/options.ts @@ -83,10 +83,10 @@ export type ViteStaticCopyOptions = { */ targets: Target[] /** - * Remove the directory structure. - * @default true + * Preserve the directory structure. + * @default false */ - flatten?: boolean + structured?: boolean /** * Suppress console output. * @default false @@ -107,7 +107,7 @@ export type ViteStaticCopyOptions = { export type ResolvedViteStaticCopyOptions = { targets: Target[] - flatten: boolean + structured: boolean silent: boolean watch: { options: WatchOptions @@ -119,7 +119,7 @@ export const resolveOptions = ( options: ViteStaticCopyOptions ): ResolvedViteStaticCopyOptions => ({ targets: options.targets, - flatten: options.flatten ?? true, + structured: options.structured ?? false, silent: options.silent ?? false, watch: { options: options.watch?.options ?? {}, diff --git a/src/serve.ts b/src/serve.ts index 8aa9b8a..76984ac 100644 --- a/src/serve.ts +++ b/src/serve.ts @@ -21,7 +21,7 @@ export type FileMap = Map export const servePlugin = ({ targets, - flatten, + structured, watch, silent }: ResolvedViteStaticCopyOptions): Plugin => { @@ -34,7 +34,7 @@ export const servePlugin = ({ const copyTargets = await collectCopyTargets( config.root, targets, - flatten + structured ) updateFileMapFromTargets(copyTargets, fileMap) } catch (e) { diff --git a/src/utils.ts b/src/utils.ts index 3a8dc62..bfcb463 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -38,7 +38,7 @@ async function renameTarget( export const collectCopyTargets = async ( root: string, targets: Target[], - flatten: boolean + structured: boolean ) => { const copyTargets: Array = [] @@ -74,7 +74,7 @@ export const collectCopyTargets = async ( const dirClean = dir.replace(/^(?:\.\.\/)+/, '') const destClean = `${dest}/${dirClean}`.replace(/^\/+|\/+$/g, '') - const destDir = flatten || (!flatten && !dir) ? dest : destClean + const destDir = !structured || (structured && !dir) ? dest : destClean copyTargets.push({ src: matchedPath, @@ -136,9 +136,9 @@ export const copyAll = async ( rootSrc: string, rootDest: string, targets: Target[], - flatten: boolean + structured: boolean ) => { - const copyTargets = await collectCopyTargets(rootSrc, targets, flatten) + const copyTargets = await collectCopyTargets(rootSrc, targets, structured) let copiedCount = 0 for (const copyTarget of copyTargets) { diff --git a/test/fixtures/package.json b/test/fixtures/package.json index 7ecef74..ae481d0 100644 --- a/test/fixtures/package.json +++ b/test/fixtures/package.json @@ -8,8 +8,8 @@ "build:absolute": "vite --config vite.absolute.config.ts build", "dev:base": "vite --config vite.base.config.ts", "build:base": "vite --config vite.base.config.ts build", - "dev:noflatten": "vite --config vite.noflatten.config.ts", - "build:noflatten": "vite --config vite.noflatten.config.ts build" + "dev:structured": "vite --config vite.structured.config.ts", + "build:structured": "vite --config vite.structured.config.ts build" }, "devDependencies": { "vite": "^4.3.5", diff --git a/test/fixtures/vite.noflatten.config.ts b/test/fixtures/vite.structured.config.ts similarity index 92% rename from test/fixtures/vite.noflatten.config.ts rename to test/fixtures/vite.structured.config.ts index 788312a..e09d6bc 100644 --- a/test/fixtures/vite.noflatten.config.ts +++ b/test/fixtures/vite.structured.config.ts @@ -3,7 +3,7 @@ import { viteStaticCopy } from 'vite-plugin-static-copy' export default defineConfig({ build: { - outDir: './dist-noflatten' + outDir: './dist-structured' }, plugins: [ viteStaticCopy({ @@ -33,7 +33,7 @@ export default defineConfig({ dest: '' } ], - flatten: false + structured: true }) ] }) diff --git a/test/testcases.ts b/test/testcases.ts index 9a1e58b..959edfb 100644 --- a/test/testcases.ts +++ b/test/testcases.ts @@ -131,7 +131,7 @@ export const testcases: Record = { dest: '/base/fixture1/foo.txt' } ], - 'vite.noflatten.config.ts': [ + 'vite.structured.config.ts': [ { name: 'glob without dir', src: './foo.txt', From 1ee0acf34eb9860c2e1607257ebb7357b69fee7d Mon Sep 17 00:00:00 2001 From: sapphi-red <49056869+sapphi-red@users.noreply.github.com> Date: Sat, 3 Jun 2023 19:41:07 +0900 Subject: [PATCH 5/5] chore: small changes --- README.md | 2 +- src/options.ts | 2 ++ src/utils.ts | 12 ++++++++---- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 02333af..a55511c 100644 --- a/README.md +++ b/README.md @@ -70,4 +70,4 @@ See [options.ts](https://github.com/sapphi-red/vite-plugin-static-copy/blob/main - Because `fast-glob` is used inside `vite`. - `transform` could return `null` as a way to tell the plugin not to copy the file, this is similar to the [CopyWebpackPlugin#filter](https://webpack.js.org/plugins/copy-webpack-plugin/#filter) option, but it expects `transform` to return the original content in case you want it to be copied. - `transform` can optionally be an object, with a `handler` property (with the same signature of the `rollup-plugin-copy` transform option) and an `encoding` property (`BufferEncoding | 'buffer'`) that will be used to read the file content so that the `handler`'s content argument will reflect the correct encoding (could be Buffer); -- `structured: true` preserves the directory structure. It is similar to `flatten: false` in `rollup-plugin-copy`, but it covers more edge cases. +- `structured: true` preserves the directory structure. This is similar to `flatten: false` in `rollup-plugin-copy`, but it covers more edge cases. diff --git a/src/options.ts b/src/options.ts index 11606c9..219aec2 100644 --- a/src/options.ts +++ b/src/options.ts @@ -84,6 +84,8 @@ export type ViteStaticCopyOptions = { targets: Target[] /** * Preserve the directory structure. + * + * Similar to `flatten: false` in rollup-plugin-copy * @default false */ structured?: boolean diff --git a/src/utils.ts b/src/utils.ts index bfcb463..563045d 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -69,12 +69,16 @@ export const collectCopyTargets = async ( } } - // https://github.com/vladshcherbin/rollup-plugin-copy/blob/507bf5e99aa2c6d0d858821e627cb7617a1d9a6d/src/index.js#L32-L35 const { base, dir } = path.parse(matchedPath) - const dirClean = dir.replace(/^(?:\.\.\/)+/, '') - const destClean = `${dest}/${dirClean}`.replace(/^\/+|\/+$/g, '') - const destDir = !structured || (structured && !dir) ? dest : destClean + let destDir: string + if (!structured || !dir) { + destDir = dest + } else { + const dirClean = dir.replace(/^(?:\.\.\/)+/, '') + const destClean = `${dest}/${dirClean}`.replace(/^\/+|\/+$/g, '') + destDir = destClean + } copyTargets.push({ src: matchedPath,