From 0b667d13017f5a26f9fc210348c4f66d7999703c Mon Sep 17 00:00:00 2001 From: Filipe Laborde Date: Mon, 4 Nov 2024 17:13:56 -0500 Subject: [PATCH 01/11] Enhanced transform functionality to include compression (zlib: gzip, brotli, deflate) --- README.md | 23 +++++++++++++++++++++++ src/options.ts | 1 + src/utils.ts | 33 ++++++++++++++++++++++++++++++++- 3 files changed, 56 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 1b6d73c..a2369ac 100644 --- a/README.md +++ b/README.md @@ -56,6 +56,29 @@ So the file will be copied to `dist/wasm-files/example.wasm`. > > See [`fast-glob` documentation about this](https://github.com/mrmlnc/fast-glob#how-to-write-patterns-on-windows) for more details. +## Usage (Compressing Content) + +Add `viteStaticCopy` plugin to `vite.config.js` / `vite.config.ts`. Destination files will now be compressed with selected algorithm (gzip, brotli, deflate) and have corresponding extension. + +```js +// vite.config.js / vite.config.ts +import { viteStaticCopy } from 'vite-plugin-static-copy' + +export default { + plugins: [ + viteStaticCopy({ + targets: [ + { + src: 'images/*.svg', + dest: 'assets', + transform: { compress: 'gzip' } + } + ] + }) + ] +} +``` + ### Options See [options.ts](https://github.com/sapphi-red/vite-plugin-static-copy/blob/main/src/options.ts). diff --git a/src/options.ts b/src/options.ts index 22e3233..d62bdfb 100644 --- a/src/options.ts +++ b/src/options.ts @@ -22,6 +22,7 @@ export type TransformOptionObject = | { encoding: Exclude handler: TransformFunc + compress?: 'gzip' | 'brotli' | 'deflate' } | { encoding: 'buffer' diff --git a/src/utils.ts b/src/utils.ts index b5d5dfc..5f3c881 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -105,6 +105,32 @@ export const collectCopyTargets = async ( return copyTargets } +async function getCompressedContent( + file: string, + transform: TransformOptionObject +) { + let destExt; + switch(transform.compress){ + case 'brotliCompress': destExt = '.br'; break; + case 'deflate': destExt = '.zz'; break; + case 'gzip': destExt = '.gz'; break; + default: destExt = ''; break; + } + //unknown encoding, return empty compressed + if(destExt == ""){ + return { destExt, transformedContent: null }; + } + + const content = await fs.readFile(file) + + const data = await new Promise((resolve, reject) => { + zlib[transform.compress](content, {}, (err, result) => { + if (err) reject(err); else resolve(result); + })}); + + return { destExt, data } +} + export async function getTransformedContent( file: string, transform: TransformOptionObject @@ -137,7 +163,12 @@ async function transformCopy( } } - const transformedContent = await getTransformedContent(src, transform) + const compressed = await getCompressedContent(src, transform) + // if this worked, adjust dest and use, else retry with getTransformedContent() + if( compressed.destExt ){ + dest += compressed.destExt; + } + const transformedContent = compressed.data ? compressed.data : await getTransformedContent(src, transform) if (transformedContent === null) { return { copied: false } } From 3535bf5905ca3c5dd9fdb3e28c4edbd9a327fb17 Mon Sep 17 00:00:00 2001 From: Filipe Laborde Date: Mon, 4 Nov 2024 17:23:11 -0500 Subject: [PATCH 02/11] Enhanced transform functionality to include compression --- src/utils.ts | 38 +++++++++++++++++++++++++------------- 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/src/utils.ts b/src/utils.ts index 5f3c881..9c6be5d 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -109,24 +109,34 @@ async function getCompressedContent( file: string, transform: TransformOptionObject ) { - let destExt; - switch(transform.compress){ - case 'brotliCompress': destExt = '.br'; break; - case 'deflate': destExt = '.zz'; break; - case 'gzip': destExt = '.gz'; break; - default: destExt = ''; break; + let destExt + switch (transform.compress) { + case 'brotliCompress': + destExt = '.br' + break + case 'deflate': + destExt = '.zz' + break + case 'gzip': + destExt = '.gz' + break + default: + destExt = '' + break } //unknown encoding, return empty compressed - if(destExt == ""){ - return { destExt, transformedContent: null }; + if (destExt == '') { + return { destExt, transformedContent: null } } const content = await fs.readFile(file) const data = await new Promise((resolve, reject) => { zlib[transform.compress](content, {}, (err, result) => { - if (err) reject(err); else resolve(result); - })}); + if (err) reject(err) + else resolve(result) + }) + }) return { destExt, data } } @@ -165,10 +175,12 @@ async function transformCopy( const compressed = await getCompressedContent(src, transform) // if this worked, adjust dest and use, else retry with getTransformedContent() - if( compressed.destExt ){ - dest += compressed.destExt; + if (compressed.destExt) { + dest += compressed.destExt } - const transformedContent = compressed.data ? compressed.data : await getTransformedContent(src, transform) + const transformedContent = compressed.data + ? compressed.data + : await getTransformedContent(src, transform) if (transformedContent === null) { return { copied: false } } From a8e98d2f14190aaeae0d0e3944e3610b8bc7001b Mon Sep 17 00:00:00 2001 From: Filipe Laborde Date: Mon, 4 Nov 2024 17:27:13 -0500 Subject: [PATCH 03/11] Enhanced transform functionality to include compression --- src/options.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/options.ts b/src/options.ts index d62bdfb..3f063ee 100644 --- a/src/options.ts +++ b/src/options.ts @@ -27,6 +27,7 @@ export type TransformOptionObject = | { encoding: 'buffer' handler: TransformFunc + compress?: 'gzip' | 'brotli' | 'deflate' } export type TransformOption = TransformFunc | TransformOptionObject From 4facee6b1947f391dfd4c0e8401fec5722df5731 Mon Sep 17 00:00:00 2001 From: Filipe Laborde Date: Mon, 4 Nov 2024 17:28:54 -0500 Subject: [PATCH 04/11] Enhanced transform functionality to include compression --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a2369ac..b9f007f 100644 --- a/README.md +++ b/README.md @@ -70,7 +70,7 @@ export default { targets: [ { src: 'images/*.svg', - dest: 'assets', + dest: 'assets', transform: { compress: 'gzip' } } ] From 1faaa3df5a45598f6e4b0970d5b25be6753c667a Mon Sep 17 00:00:00 2001 From: Filipe Laborde Date: Mon, 4 Nov 2024 17:30:53 -0500 Subject: [PATCH 05/11] Enhanced transform functionality to include compression --- src/options.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/options.ts b/src/options.ts index 3f063ee..8043144 100644 --- a/src/options.ts +++ b/src/options.ts @@ -22,12 +22,12 @@ export type TransformOptionObject = | { encoding: Exclude handler: TransformFunc - compress?: 'gzip' | 'brotli' | 'deflate' + compress?: 'gzip' | 'brotliCompress' | 'deflate' } | { encoding: 'buffer' handler: TransformFunc - compress?: 'gzip' | 'brotli' | 'deflate' + compress?: 'gzip' | 'brotliCompress' | 'deflate' } export type TransformOption = TransformFunc | TransformOptionObject From 504208287837afad49e6d42000b7aa483a732efa Mon Sep 17 00:00:00 2001 From: Filipe Laborde Date: Mon, 4 Nov 2024 17:36:12 -0500 Subject: [PATCH 06/11] Enhanced transform functionality to include compression --- src/utils.ts | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/utils.ts b/src/utils.ts index 9c6be5d..63e0d5d 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -11,6 +11,7 @@ import type { import type { Logger } from 'vite' import type { FileMap } from './serve' import { createHash } from 'node:crypto' +import zlib from 'zlib'; export type SimpleTarget = { src: string @@ -126,17 +127,17 @@ async function getCompressedContent( } //unknown encoding, return empty compressed if (destExt == '') { - return { destExt, transformedContent: null } + return { destExt, data: null } } const content = await fs.readFile(file) - const data = await new Promise((resolve, reject) => { - zlib[transform.compress](content, {}, (err, result) => { - if (err) reject(err) - else resolve(result) - }) - }) + const data = await new Promise((resolve, reject) => { + zlib[transform.compress](content, (err: Error | null, result: Buffer) => { + if (err) reject(err); + else resolve(result); + }); + }); return { destExt, data } } From ca0952bc0e90979ae9f9d28023a31b8b1187b2c0 Mon Sep 17 00:00:00 2001 From: Filipe Laborde Date: Mon, 4 Nov 2024 17:36:44 -0500 Subject: [PATCH 07/11] Enhanced transform functionality to include compression --- src/utils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils.ts b/src/utils.ts index 63e0d5d..0cfff4b 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -11,7 +11,7 @@ import type { import type { Logger } from 'vite' import type { FileMap } from './serve' import { createHash } from 'node:crypto' -import zlib from 'zlib'; +import zlib from 'zlib' export type SimpleTarget = { src: string From fed8bf237354bb9816623cee3052fd19cfe1b301 Mon Sep 17 00:00:00 2001 From: Filipe Laborde Date: Mon, 4 Nov 2024 17:39:25 -0500 Subject: [PATCH 08/11] Enhanced transform functionality to include compression --- src/utils.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/utils.ts b/src/utils.ts index 0cfff4b..9957be2 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -134,10 +134,10 @@ async function getCompressedContent( const data = await new Promise((resolve, reject) => { zlib[transform.compress](content, (err: Error | null, result: Buffer) => { - if (err) reject(err); - else resolve(result); - }); - }); + if (err) reject(err) + else resolve(result) + }) + }) return { destExt, data } } From 3575b77f3137dff4504d2a5834a3d45d93cdb562 Mon Sep 17 00:00:00 2001 From: Filipe Laborde Date: Mon, 4 Nov 2024 17:42:25 -0500 Subject: [PATCH 09/11] Enhanced transform functionality to include compression --- src/utils.ts | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/utils.ts b/src/utils.ts index 9957be2..c9417ff 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -133,10 +133,13 @@ async function getCompressedContent( const content = await fs.readFile(file) const data = await new Promise((resolve, reject) => { - zlib[transform.compress](content, (err: Error | null, result: Buffer) => { - if (err) reject(err) - else resolve(result) - }) + zlib[transform.compress || 'gzip']( + content, + (err: Error | null, result: Buffer) => { + if (err) reject(err) + else resolve(result) + } + ) }) return { destExt, data } From 7b3b781440440c2c27b3244efbd219b262ba73dd Mon Sep 17 00:00:00 2001 From: Filipe Laborde Date: Mon, 4 Nov 2024 18:11:42 -0500 Subject: [PATCH 10/11] Enhanced transform functionality to include compression --- src/utils.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/utils.ts b/src/utils.ts index c9417ff..dd36a5e 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -177,13 +177,13 @@ async function transformCopy( } } - const compressed = await getCompressedContent(src, transform) + const { destExt, data } = await getCompressedContent(src, transform) // if this worked, adjust dest and use, else retry with getTransformedContent() - if (compressed.destExt) { - dest += compressed.destExt + if (destExt) { + dest += destExt } - const transformedContent = compressed.data - ? compressed.data + const transformedContent = destExt + ? data : await getTransformedContent(src, transform) if (transformedContent === null) { return { copied: false } From e729953aec2c395ba2b62b5bd432dc2919dfe09d Mon Sep 17 00:00:00 2001 From: Filipe Laborde Date: Mon, 4 Nov 2024 18:18:57 -0500 Subject: [PATCH 11/11] Enhanced transform functionality to include compression --- src/utils.ts | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/src/utils.ts b/src/utils.ts index dd36a5e..b579a3a 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -127,12 +127,12 @@ async function getCompressedContent( } //unknown encoding, return empty compressed if (destExt == '') { - return { destExt, data: null } + return { destExt, compressedData: null } } const content = await fs.readFile(file) - const data = await new Promise((resolve, reject) => { + const compressedData = await new Promise((resolve, reject) => { zlib[transform.compress || 'gzip']( content, (err: Error | null, result: Buffer) => { @@ -142,7 +142,7 @@ async function getCompressedContent( ) }) - return { destExt, data } + return { destExt, compressedData } } export async function getTransformedContent( @@ -177,18 +177,20 @@ async function transformCopy( } } - const { destExt, data } = await getCompressedContent(src, transform) + const { destExt, compressedData } = await getCompressedContent(src, transform) // if this worked, adjust dest and use, else retry with getTransformedContent() if (destExt) { - dest += destExt - } - const transformedContent = destExt - ? data - : await getTransformedContent(src, transform) - if (transformedContent === null) { - return { copied: false } + if (compressedData === null) { + return { copied: false } + } + await fs.outputFile(dest + destExt, compressedData) + } else { + const transformedContent = await getTransformedContent(src, transform) + if (transformedContent === null) { + return { copied: false } + } + await fs.outputFile(dest, transformedContent) } - await fs.outputFile(dest, transformedContent) return { copied: true } }