vite-plugin-fflate-zip
Version:
Vite plugin for packaging build folder into zip file via fflate
1 lines • 9.2 kB
Source Map (JSON)
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import { existsSync, mkdirSync, readFileSync, readdirSync, statSync, writeFileSync } from 'node:fs'\nimport { join } from 'node:path'\nimport { cwd } from 'node:process'\nimport { cyan, getRootByPackageName, gray, green, red } from '@heybrostudio/utils'\nimport { zipSync } from 'fflate'\nimport type { Plugin } from 'vite'\nimport path from 'node:path';\n\nexport interface ZipPackageFile {\n\t/**\n\t * The resolved file or directory\n\t */\n src: string;\n\t/**\n\t * set a prefix for the file or directory\n\t */\n prefix?:string;\n\t/**\n\t * Files to be excluded\n\t */\n\texcludedFiles?: string[]\n}\n\nexport interface Options {\n\t/**\n\t * Input Directory\n\t * @default `dist`\n\t */\n\tinDir?: string\n\n\t/**\n\t * A list of files or directories with preifx and exclusions.\n\t */\n\tfiles?: ZipPackageFile[];\n\n\t/**\n\t * Output Directory\n\t * @default `dist-zip`\n\t */\n\toutDir: string\n\t/**\n\t * Zip Archive Name.\n\t * @default `${pkg.name}-${pkg.version}.zip`\n\t */\n\tzipName: string\n\t/**\n\t * Files to be excluded\n\t */\n\texcludedFiles?: string[]\n\t/**\n\t * After creating the zip file execute\n\t */\n\tonArchived: () => void\n\t/**\n\t * Execute when an error occurs\n\t * @param err Error message\n\t */\n\tonError: (err: Error) => void\n}\n\nconst ROOT_DIR = cwd()\nconst ALREADY_COMPRESSED = [\n\t'zip',\n\t'gz',\n\t'png',\n\t'jpg',\n\t'jpeg',\n\t'pdf',\n\t'doc',\n\t'docx',\n\t'ppt',\n\t'pptx',\n\t'xls',\n\t'xlsx',\n\t'heic',\n\t'heif',\n\t'7z',\n\t'bz2',\n\t'rar',\n\t'gif',\n\t'webp',\n\t'webm',\n\t'mp4',\n\t'mov',\n\t'mp3',\n\t'aifc',\n]\nfunction buildZipData(files: ZipPackageFile[]) {\n\tconst zipData = new Map()\n\t\n\t/**\n\t * Build zip structure from a file or directory entry\n\t * @param file \n\t */\n\tfunction _buildStructure(file: ZipPackageFile) {\n\n\t\tif (file.src.indexOf(\".\") > -1) {\n\t\t\t//build an individual file\n\t\t\t_buildFile(file.src,path.join(file.prefix || \"\", path.basename(file.src)) );\n\t\t} else {\n\t\t\t//build a directory\n\t\t\t_build(file.src, file.src, file.prefix, file.excludedFiles);\n\t\t}\n\t}\n\n\tfunction _buildFile(resolvedFile: string, prefix: string) {\n\t\tconst ext = resolvedFile.slice(resolvedFile.lastIndexOf('.') + 1).toLowerCase();\n\t\tzipData.set(prefix, [\n\t\t\treadFileSync(resolvedFile),\n\t\t\t{\n\t\t\t\tlevel: !ALREADY_COMPRESSED.includes(ext) ? 6 : 0,\n\t\t\t},\n\t\t])\n\t}\n\n\tfunction _build(dir: string, baseDir: string, prefix = '', excludedFiles: string[] = []) {\n\t\tconst allPaths = readdirSync(dir)\n\n\t\tfor (const file of allPaths) {\n\t\t\tif (excludedFiles?.includes(file)) continue;\n\t\t\tconst resolvedFile = join(dir, file);\n\t\t\tif (statSync(resolvedFile).isDirectory()) {\n\t\t\t\t_build(resolvedFile, baseDir, prefix, excludedFiles);\n\t\t\t} else {\n\t\t\t\t//Add file replacing the base directory with a prefix path if set.\n\t\t\t\t_buildFile(resolvedFile, path.join(prefix, path.relative(baseDir, resolvedFile)));\n\t\t\t}\n\t\t}\n\t}\n\n\t//Create zip structure from a set of files and directories\n\tfiles.map(file => {\n\t\t_buildStructure(file);\n\t});\n\n\treturn zipData;\n}\n\nconst _options: Options = {\n\tinDir: '',\n\toutDir: 'dist-zip',\n\tzipName: '',\n\texcludedFiles: [],\n\tonArchived: () => {},\n\tonError: () => {},\n}\nexport default function fflateZip(options: Partial<Options> = {}): Plugin {\n\treturn {\n\t\tname: 'vite-plugin-fflate-zip',\n\t\tapply: 'build',\n\t\tenforce: 'post',\n\t\tconfigResolved(config) {\n\t\t\ttry {\n\t\t\t\tconst { root, build } = config\n\n\t\t\t\tObject.assign(\n\t\t\t\t\t_options,\n\t\t\t\t\t{\n\t\t\t\t\t\tinDir: build.outDir,\n\t\t\t\t\t},\n\t\t\t\t\t{ ...options },\n\t\t\t\t)\n\n\t\t\t\tif (!_options?.zipName) {\n\t\t\t\t\tconst pkgBuffer = readFileSync(join(root, 'package.json'))\n\t\t\t\t\tconst pkg = JSON.parse(pkgBuffer.toString())\n\t\t\t\t\t_options.zipName = `${pkg.name}-${pkg.version}`\n\t\t\t\t}\n\t\t\t} catch (err) {\n\t\t\t\tif (err) red(err as string)\n\n\t\t\t\t_options.onError(err as Error)\n\t\t\t}\n\t\t},\n\t\tcloseBundle() {\n\t\t\ttry {\n\t\t\t\t// Get fflate version number\n\t\t\t\tconst FFLATE = 'fflate'\n\t\t\t\tconst fflateRoot = getRootByPackageName(FFLATE)\n\t\t\t\tconst fflateVersion = JSON.parse(readFileSync(join(fflateRoot, 'package.json')).toString()).version\n\n\t\t\t\tconsole.log(cyan(`⚡️${FFLATE} v${fflateVersion}`), green('zipping for production...'))\n\n\t\t\t\tconst { inDir, outDir, zipName } = _options\n\t\t\t\t// validate input directory\n\t\t\t\tif (inDir && !existsSync(inDir)) throw new Error(`\"${inDir}\" folder does not exist!`)\n\t\t\t\t// validate output directory. If it does not exist, create\n\t\t\t\tif (!existsSync(outDir)) mkdirSync(outDir, { recursive: true })\n\n\t\t\t\t// Build zip data\n\t\t\t\tconst startTime = Date.now()\n\n\t\t\t\t//add in directory to files list if set\n\t\t\t\tif (!options.files && inDir) {\n\t\t\t\t\toptions.files = [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tsrc: join(ROOT_DIR, inDir),\n\t\t\t\t\t\t\t//set exclude file list if set\n\t\t\t\t\t\t\texcludedFiles: options.excludedFiles\n\t\t\t\t\t\t}\n\t\t\t\t\t];\n\t\t\t\t}\n\n\t\t\t\tconst zipData = buildZipData(options.files!);\n\n\t\t\t\tconst zipOutput = zipSync(Object.fromEntries(zipData), { level: 6 })\n\n\t\t\t\t// Build .zip file\n\t\t\t\tconst outputZipFile = join(ROOT_DIR, outDir, `${zipName}.zip`)\n\t\t\t\twriteFileSync(outputZipFile, zipOutput)\n\n\t\t\t\t// Get zip size\n\t\t\t\tconst zipSize = `${(statSync(outputZipFile).size / 1024).toFixed(2)} kB`\n\t\t\t\tconsole.log(gray(`${outDir}/${cyan(zipName)}${cyan('.zip')}`), cyan(`| ${zipSize}`))\n\n\t\t\t\t_options.onArchived()\n\t\t\t\tconsole.log(green(`✓ zip in ${Date.now() - startTime}ms`))\n\t\t\t} catch (err) {\n\t\t\t\tif (err) console.log(red(err as string))\n\n\t\t\t\t_options.onError(err as Error)\n\t\t\t}\n\t\t},\n\t}\n}\n"],"mappings":"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","names":["src_exports","__export","fflateZip","__toCommonJS","import_node_fs","import_node_path","import_node_process","import_utils","import_fflate","ROOT_DIR","ALREADY_COMPRESSED","buildZipData","files","zipData","_buildStructure","file","_buildFile","path","_build","resolvedFile","prefix","ext","dir","baseDir","excludedFiles","allPaths","_options","options","config","root","build","pkgBuffer","pkg","err","FFLATE","fflateRoot","fflateVersion","inDir","outDir","zipName","startTime","zipOutput","outputZipFile","zipSize"]}