zcompress-vite-plugin 0.1.2 → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/index.js +38 -32
  2. package/install.js +6 -4
  3. package/package.json +1 -1
package/index.js CHANGED
@@ -2,7 +2,7 @@
2
2
  * zcompress Vite Plugin
3
3
  *
4
4
  * A Vite plugin that compresses build output using the zcompress CLI.
5
- * Provides multi-threaded gzip/zstd compression for production builds.
5
+ * Provides multi-threaded gzip/zstd/brotli compression for production builds.
6
6
  *
7
7
  * @example
8
8
  * // vite.config.js
@@ -16,8 +16,11 @@
16
16
  */
17
17
 
18
18
  import { execSync } from 'node:child_process';
19
- import { existsSync, statSync } from 'node:fs';
20
- import { join } from 'node:path';
19
+ import { existsSync, statSync, readdirSync } from 'node:fs';
20
+ import { join, dirname, isAbsolute } from 'node:path';
21
+ import { fileURLToPath } from 'node:url';
22
+
23
+ const __dirname = dirname(fileURLToPath(import.meta.url));
21
24
 
22
25
  /**
23
26
  * @typedef {Object} ZCompressOptions
@@ -44,15 +47,14 @@ const DEFAULT_OPTIONS = {
44
47
 
45
48
  /**
46
49
  * Find the zcompress binary.
47
- * Order: 1) downloaded by postinstall 2) PATH 3) local zig build
50
+ * Order: 1) downloaded by postinstall 2) local zig build 3) PATH
48
51
  */
49
52
  function findBinary() {
50
- // 1. Check for postinstall-downloaded binary
51
- const binDir = join(__dirname, 'bin');
52
- const localBin = join(binDir, process.platform === 'win32' ? 'zcompress.exe' : 'zcompress');
53
- if (existsSync(localBin)) return localBin;
53
+ // 1) postinstall-downloaded binary inside package
54
+ const packagedBin = join(__dirname, 'bin', process.platform === 'win32' ? 'zcompress.exe' : 'zcompress');
55
+ if (existsSync(packagedBin)) return packagedBin;
54
56
 
55
- // 2. Check local zig build
57
+ // 2) local zig build
56
58
  const zigPaths = [
57
59
  join(process.cwd(), 'zig-out', 'bin', 'zcompress'),
58
60
  join(process.cwd(), 'zig-out', 'bin', 'zcompress.exe'),
@@ -61,7 +63,7 @@ function findBinary() {
61
63
  if (existsSync(p)) return p;
62
64
  }
63
65
 
64
- // 3. Fall back to PATH
66
+ // 3) PATH
65
67
  return 'zcompress';
66
68
  }
67
69
 
@@ -74,20 +76,29 @@ function findBinary() {
74
76
  export default function zcompressPlugin(userOptions = {}) {
75
77
  const options = { ...DEFAULT_OPTIONS, ...userOptions };
76
78
 
79
+ // ESM-safe plugin state (do not use `this`)
80
+ let active = false;
81
+ let resolvedOutDir = 'dist';
82
+
77
83
  return {
78
84
  name: 'zcompress',
79
85
  apply: 'build',
80
86
  enforce: 'post',
81
87
 
82
88
  configResolved(config) {
83
- // Only run in production build mode
84
- this.active = config.command === 'build';
89
+ active = config.command === 'build';
90
+
91
+ // Save outDir from Vite config (Bug #2 fix)
92
+ const configuredOutDir = config.build?.outDir || 'dist';
93
+ resolvedOutDir = isAbsolute(configuredOutDir)
94
+ ? configuredOutDir
95
+ : join(config.root || process.cwd(), configuredOutDir);
85
96
  },
86
97
 
87
98
  closeBundle() {
88
- if (!this.active) return;
99
+ if (!active) return;
89
100
 
90
- const outDir = this.outDir || 'dist';
101
+ const outDir = resolvedOutDir;
91
102
  const compressedDir = `${outDir}-compressed`;
92
103
 
93
104
  if (!existsSync(outDir)) {
@@ -103,18 +114,12 @@ export default function zcompressPlugin(userOptions = {}) {
103
114
  '-l', String(options.level),
104
115
  ];
105
116
 
106
- if (options.threads > 0) {
107
- args.push('-t', String(options.threads));
108
- }
117
+ if (options.threads > 0) args.push('-t', String(options.threads));
109
118
  if (options.verbose) args.push('--verbose');
110
119
  if (options.cache) args.push('--cache');
111
120
 
112
- for (const ext of options.include) {
113
- args.push(`--include=${ext}`);
114
- }
115
- for (const ext of options.exclude) {
116
- args.push(`--exclude=${ext}`);
117
- }
121
+ for (const ext of options.include) args.push(`--include=${ext}`);
122
+ for (const ext of options.exclude) args.push(`--exclude=${ext}`);
118
123
 
119
124
  const cmd = `${binary} ${args.join(' ')}`;
120
125
 
@@ -128,7 +133,6 @@ export default function zcompressPlugin(userOptions = {}) {
128
133
  execSync(cmd, { stdio: 'inherit' });
129
134
  const elapsed = ((Date.now() - startTime) / 1000).toFixed(1);
130
135
 
131
- // Calculate size stats
132
136
  const srcSize = getDirSize(outDir);
133
137
  const destSize = getDirSize(compressedDir);
134
138
  const savedPct = srcSize > 0
@@ -152,17 +156,19 @@ export default function zcompressPlugin(userOptions = {}) {
152
156
  */
153
157
  function getDirSize(dirPath) {
154
158
  if (!existsSync(dirPath)) return 0;
155
- // Simple approximation — list files and sum their sizes
159
+
156
160
  let total = 0;
157
161
  try {
158
- const { readdirSync } = require('node:fs');
159
- const { join } = require('node:path');
160
162
  walkDir(dirPath, (filePath) => {
161
163
  try {
162
164
  total += statSync(filePath).size;
163
- } catch (_) { /* ignore */ }
165
+ } catch {
166
+ // ignore unreadable files
167
+ }
164
168
  });
165
- } catch (_) { /* ignore */ }
169
+ } catch {
170
+ // ignore traversal failures
171
+ }
166
172
  return total;
167
173
  }
168
174
 
@@ -173,8 +179,6 @@ function getDirSize(dirPath) {
173
179
  * @param {(path: string) => void} fn
174
180
  */
175
181
  function walkDir(dir, fn) {
176
- const { readdirSync } = require('node:fs');
177
- const { join } = require('node:path');
178
182
  try {
179
183
  const entries = readdirSync(dir, { withFileTypes: true });
180
184
  for (const entry of entries) {
@@ -185,7 +189,9 @@ function walkDir(dir, fn) {
185
189
  fn(full);
186
190
  }
187
191
  }
188
- } catch (_) { /* ignore */ }
192
+ } catch {
193
+ // ignore traversal failures
194
+ }
189
195
  }
190
196
 
191
197
  /**
package/install.js CHANGED
@@ -5,8 +5,7 @@
5
5
  * Falls back gracefully if the binary can't be downloaded (e.g. air-gapped, unsupported platform).
6
6
  */
7
7
 
8
- import { execSync } from 'node:child_process';
9
- import { createWriteStream, existsSync, chmodSync, mkdirSync, unlinkSync } from 'node:fs';
8
+ import { createWriteStream, existsSync, chmodSync, mkdirSync, unlinkSync, readFileSync } from 'node:fs';
10
9
  import { get } from 'node:https';
11
10
  import { join, dirname } from 'node:path';
12
11
  import { fileURLToPath } from 'node:url';
@@ -14,8 +13,11 @@ import { pipeline } from 'node:stream/promises';
14
13
 
15
14
  const __dirname = dirname(fileURLToPath(import.meta.url));
16
15
  const BIN_DIR = join(__dirname, 'bin');
17
- const VERSION = '0.1.0'; // Update on each release
18
- const REPO = 'luochuan2008/zcompress'; // Change to your GitHub username/repo
16
+ const REPO = 'luochuan2008/zcompress';
17
+
18
+ // Read package version dynamically to avoid manual sync bugs.
19
+ const pkgJson = JSON.parse(readFileSync(join(__dirname, 'package.json'), 'utf8'));
20
+ const VERSION = pkgJson.version;
19
21
 
20
22
  const PLATFORM_MAP = {
21
23
  'darwin-arm64': 'zcompress-macos-arm64',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zcompress-vite-plugin",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "description": "High-performance multi-threaded asset compression for Vite — powered by Zig",
5
5
  "type": "module",
6
6
  "main": "index.js",