From a182ebcc4d67ff7df9be9e42dcb80947ceed37f2 Mon Sep 17 00:00:00 2001 From: kanno <812137533@qq.com> Date: Sun, 3 Mar 2024 15:20:55 +0800 Subject: [PATCH] fix: tarball should work normal without compression --- README.md | 8 ++-- __tests__/{cp.spec.ts => tarball.spec.ts} | 51 ++++++++++++++++++++--- src/index.ts | 24 ++++++----- src/interface.ts | 2 +- 4 files changed, 63 insertions(+), 22 deletions(-) rename __tests__/{cp.spec.ts => tarball.spec.ts} (54%) diff --git a/README.md b/README.md index 786b65e..5d56f9d 100644 --- a/README.md +++ b/README.md @@ -77,17 +77,17 @@ export default defineComponent({ there are write (delete) operations on the bundle inside the plugin. So you should ignore the compressed chunk :) If you want delete the original assets you also follow the way. -> Can i create a tarball for all of chunks after compressed? -- Yes, you can import `cp` plugin from this package(>=12.0.0) +> Can i create a tarball for all of assets after compressed? +- Yes, you can import `tarball` plugin from this package(>=12.0.0) ```js import { defineComponent } from 'vite' -import { compression, cp } from 'vite-plugin-compression2' +import { compression, tarball } from 'vite-plugin-compression2' export default defineComponent({ plugins: [ // ...your plugin compression(), - cp({ dest: './xzy' }) + tarball() ] }) diff --git a/__tests__/cp.spec.ts b/__tests__/tarball.spec.ts similarity index 54% rename from __tests__/cp.spec.ts rename to __tests__/tarball.spec.ts index 588e1f5..9233e3a 100644 --- a/__tests__/cp.spec.ts +++ b/__tests__/tarball.spec.ts @@ -1,13 +1,13 @@ import path from 'path' +import zlib from 'zlib' import fs from 'fs' import fsp from 'fs/promises' -import zlib from 'zlib' import { build } from 'vite' import test from 'ava' import tar from 'tar-stream' import { readAll } from '../src/utils' -import type { ViteCompressionPluginConfig } from '../src' -import { compression, cp } from '../src' +import type { ViteCompressionPluginConfig, ViteTarballPluginOptions } from '../src' +import { compression, tarball } from '../src' const getId = () => Math.random().toString(32).slice(2, 10) const sleep = (delay: number) => new Promise((resolve) => setTimeout(resolve, delay)) @@ -38,7 +38,7 @@ async function mockBuild(dir = 'public-assets-nest' const id = getId() await build({ root: path.join(__dirname, 'fixtures', dir), - plugins: [compression(options), cp({ dest: path.join(dest, id) })], + plugins: [compression(options), tarball({ dest: path.join(dest, id) })], configFile: false, logLevel: 'silent', build: { @@ -48,12 +48,27 @@ async function mockBuild(dir = 'public-assets-nest' return id } +async function mockBuildwithoutCompression(dir: string, id: string, options: ViteTarballPluginOptions = {}) { + const bundle = await build({ + root: path.join(__dirname, 'fixtures', dir), + plugins: [tarball(options)], + configFile: false, + logLevel: 'silent', + build: { + outDir: path.join(dist, id) + } + }) + return { id, bundle } +} + test.after(async () => { await fsp.rm(dest, { recursive: true }) }) -test('cp', async (t) => { - const ids = await Promise.all([mockBuild('dynamic', { deleteOriginalAssets: true, skipIfLargerOrEqual: false }), mockBuild('dynamic')]) +test('tarball', async (t) => { + const ids = await Promise.all([ + mockBuild('public-assets-nest', { deleteOriginalAssets: true, skipIfLargerOrEqual: false }), + mockBuild('public-assets-nest', { skipIfLargerOrEqual: false })]) await sleep(3000) const [diff1, diff2] = await Promise.all(ids.map((id) => readAll(path.join(dist, id)))) const diff1Js = diff1.filter((v) => v.endsWith('.js.gz')).map((v) => zlib.unzipSync(fs.readFileSync(v))) @@ -66,3 +81,27 @@ test('cp', async (t) => { } } }) + +test('tarball without compression', async (t) => { + const { id, bundle } = await mockBuildwithoutCompression('normal', getId()) + const outputs = await extract(path.join(dist, id + '.tar.gz')) + if (typeof bundle === 'object' && 'output' in bundle) { + for (const chunk of bundle.output) { + if (chunk.fileName in outputs) { + const act = Buffer.from(outputs[chunk.fileName]) + if (chunk.type === 'asset') { + t.deepEqual(act, Buffer.from(chunk.source)) + } else { + t.deepEqual(act, Buffer.from(chunk.code)) + } + } + } + } +}) + +test('tarball specify output', async (t) => { + const id = getId() + await mockBuildwithoutCompression('public-assets-nest', id, { dest: path.join(dest, id) }) + const outputs = await extract(path.join(dest, id + '.tar.gz')) + t.truthy(Object.keys(outputs).length > 0) +}) diff --git a/src/index.ts b/src/index.ts index 53556e7..70a2af1 100644 --- a/src/index.ts +++ b/src/index.ts @@ -16,11 +16,12 @@ import type { ViteCompressionPluginConfig, ViteCompressionPluginConfigAlgorithm, ViteCompressionPluginConfigFunction, - ViteCpPluginOptions, + ViteTarballPluginOptions, ViteWithoutCompressionPluginConfigFunction } from './interface' const VITE_INTERNAL_ANALYSIS_PLUGIN = 'vite:build-import-analysis' +const VITE_COMPRESSION_PLUGIN = 'vite-plugin-compression' const VITE_COPY_PUBLIC_DIR = 'copyPublicDir' const MAX_CONCURRENT = (() => { const cpus = os.cpus() || { length: 1 } @@ -86,21 +87,22 @@ async function handleStaticFiles(config: ResolvedConfig, callback: (file: string } } -function cp(opts: ViteCpPluginOptions = {}): Plugin { +function tarball(opts: ViteTarballPluginOptions = {}): Plugin { const { dest: userDest } = opts const statics: string[] = [] - let outputs: string[] = [] + const outputs: string[] = [] + let dests: string[] = [] let root = process.cwd() const tarball = createTarBall() const queue = createConcurrentQueue(MAX_CONCURRENT) return { - name: 'vite-plugin-cp', + name: 'vite-plugin-tarball', enforce: 'post', async configResolved(config) { outputs.push(...handleOutputOption(config)) root = config.root - outputs = userDest ? [userDest] : outputs - tarball.setOptions({ dests: outputs, root }) + dests = userDest ? [userDest] : outputs + tarball.setOptions({ dests, root }) // No need to add source to pack in configResolved stage // If we do at the start stage. The build task will be slow. const ctx = compression.getPluginAPI(config.plugins) @@ -128,7 +130,7 @@ function cp(opts: ViteCpPluginOptions = {}): Plugin { }) } } - await queue.wait().catch(e => e) + await queue.wait() await tarball.write() } } @@ -195,7 +197,7 @@ function compression(opts } return { - name: 'vite-plugin-compression', + name: VITE_COMPRESSION_PLUGIN, apply: 'build', enforce: 'post', api: pluginContext, @@ -244,10 +246,10 @@ function compression(opts } compression.getPluginAPI = (plugins: readonly Plugin[]): CompressionPluginAPI | undefined => - plugins.find(p => p.name === 'vite-plugin-compression')?.api + plugins.find(p => p.name === VITE_COMPRESSION_PLUGIN)?.api -export { compression, cp } +export { compression, tarball } export default compression -export type { CompressionOptions, Algorithm, ViteCompressionPluginConfig, ViteCpPluginOptions } from './interface' +export type { CompressionOptions, Algorithm, ViteCompressionPluginConfig, ViteTarballPluginOptions } from './interface' diff --git a/src/interface.ts b/src/interface.ts index 4193f8a..fc47042 100644 --- a/src/interface.ts +++ b/src/interface.ts @@ -61,6 +61,6 @@ export type ViteCompressionPluginConfig = export type GenerateBundle = HookHandler -export interface ViteCpPluginOptions { +export interface ViteTarballPluginOptions { dest?: string, }