@rsbuild/plugin-image-compress 1.0.2 → 1.2.0

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.
package/README.md CHANGED
@@ -9,6 +9,7 @@ With the image compression plugin, image assets used in the project can be compr
9
9
  <img src="https://img.shields.io/npm/v/@rsbuild/plugin-image-compress?style=flat-square&colorA=564341&colorB=EDED91" alt="npm version" />
10
10
  </a>
11
11
  <img src="https://img.shields.io/badge/License-MIT-blue.svg?style=flat-square&colorA=564341&colorB=EDED91" alt="license" />
12
+ <a href="https://npmcharts.com/compare/@rsbuild/plugin-image-compress?minimal=true"><img src="https://img.shields.io/npm/dm/@rsbuild/plugin-image-compress.svg?style=flat-square&colorA=564341&colorB=EDED91" alt="downloads" /></a>
12
13
  </p>
13
14
 
14
15
  ## Usage
@@ -30,10 +31,9 @@ export default {
30
31
  };
31
32
  ```
32
33
 
33
- ## Options
34
+ This plugin is compatible with both Rsbuild and Rspack. If you are using Rspack instead of Rsbuild, you can import the `ImageMinimizerPlugin` from the package, see [Rspack Usage](#rspack-usage).
34
35
 
35
- The plugin accepts an array of compressor configuration options, each of which can be either a string or an object. The string can be the name of a built-in compressor and its default configuration enabled.
36
- Or use the object format configuration and specify the compressor in the `use` field. The remaining fields of the object will be used as compressor configuration options.
36
+ ## Default Compressors
37
37
 
38
38
  By default, the plugin will enable `jpeg`, `png`, `ico` image compressors, which are equivalent to the following two examples:
39
39
 
@@ -45,19 +45,48 @@ pluginImageCompress(["jpeg", "png", "ico"]);
45
45
  pluginImageCompress([{ use: "jpeg" }, { use: "png" }, { use: "ico" }]);
46
46
  ```
47
47
 
48
+ ## Supported Compressors
49
+
50
+ The plugin supports the following compressors:
51
+
52
+ - `jpeg`: For JPEG images.
53
+ - `png`: For PNG images.
54
+ - `pngLossless`: For PNG images with lossless compression.
55
+ - `ico`: For ICO images.
56
+ - `svg`: For SVG images.
57
+ - `avif`: For AVIF images.
58
+
59
+ Only SVG are compressed by `svgo`, other compressors are compressed by `@napi-rs/image`.
60
+
61
+ ## Options
62
+
63
+ The plugin accepts an array of compressor configuration options, each of which can be either a string or an object. The string can be the name of a built-in compressor and its default configuration enabled.
64
+
65
+ Or use the object format configuration and specify the compressor in the `use` field. The remaining fields of the object will be used as compressor configuration options.
66
+
48
67
  The default configuration can be overridden by specifying a configuration option.
49
68
  For example, to allow the jpeg compressor to recognize new extension name and to set the quality of the png compressor.
50
69
 
51
70
  ```js
52
71
  pluginImageCompress([
72
+ // Options for @napi-rs/image `compressJpeg` method
53
73
  { use: "jpeg", test: /\.(?:jpg|jpeg|jpe)$/ },
74
+ // Options for @napi-rs/image `pngQuantize` method
54
75
  { use: "png", minQuality: 50 },
55
- "ico",
76
+ // Options for @napi-rs/image `avif` method
77
+ { use: "avif", quality: 80 },
78
+ // Options for svgo
79
+ { use: 'svg', floatPrecision: 2 }
80
+ // No options yet
81
+ { use: "ico" },
56
82
  ]);
57
83
  ```
58
84
 
59
- The default `png` compressor is lossy.
60
- If you want to replace it with a lossless compressor, you can use the following configuration.
85
+ For more information on compressors, please visit [@napi-rs/image](https://image.napi.rs/docs).
86
+
87
+ ## Lossless PNG
88
+
89
+ The default `png` compressor is lossy. If you want to replace it with a lossless compressor, you can use the following configuration.
61
90
 
62
91
  ```js
63
92
  pluginImageCompress(["jpeg", "pngLossless", "ico"]);
@@ -71,7 +100,51 @@ For example, the `png` compressor will take precedence over the `pngLossless` co
71
100
  pluginImageCompress(["jpeg", "pngLossless", "ico", "png"]);
72
101
  ```
73
102
 
74
- For more information on compressors, please visit [@napi-rs/image](https://image.napi.rs/docs).
103
+ ## Rspack Usage
104
+
105
+ The plugin is also compatible with Rspack.
106
+
107
+ If you are using Rspack instead of Rsbuild, you can import the `ImageMinimizerPlugin` from the package, use it in the [optimization.minimizer](https://rspack.dev/config/optimization#optimizationminimizer) array.
108
+
109
+ ```ts
110
+ // rspack.config.mjs
111
+ import { ImageMinimizerPlugin } from "@rsbuild/plugin-image-compress";
112
+ import { defineConfig } from "@rspack/cli";
113
+
114
+ export default defineConfig({
115
+ mode: process.env.NODE_ENV === "production" ? "production" : "development",
116
+ optimization: {
117
+ minimizer: [
118
+ // Use `...` to preserve the default JS and CSS minimizers of Rspack
119
+ '...',
120
+ // Add the image minimizer plugins
121
+ new ImageMinimizerPlugin({
122
+ use: "jpeg",
123
+ test: /\.(?:jpg|jpeg)$/,
124
+ }),
125
+ new ImageMinimizerPlugin({
126
+ use: "png",
127
+ test: /\.png$/,
128
+ maxQuality: 50,
129
+ }),
130
+ new ImageMinimizerPlugin({
131
+ use: "avif",
132
+ test: /\.avif$/,
133
+ quality: 80,
134
+ }),
135
+ new ImageMinimizerPlugin({
136
+ use: "svg",
137
+ test: /\.svg$/,
138
+ floatPrecision: 2,
139
+ }),
140
+ new ImageMinimizerPlugin({
141
+ use: "ico",
142
+ test: /\.(?:ico|icon)$/,
143
+ }),
144
+ ],
145
+ },
146
+ });
147
+ ```
75
148
 
76
149
  ## License
77
150
 
package/dist/index.cjs CHANGED
@@ -1,226 +1,241 @@
1
1
  "use strict";
2
- var __create = Object.create;
3
- var __defProp = Object.defineProperty;
4
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
- var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __getProtoOf = Object.getPrototypeOf;
7
- var __hasOwnProp = Object.prototype.hasOwnProperty;
8
- var __export = (target, all) => {
9
- for (var name in all)
10
- __defProp(target, name, { get: all[name], enumerable: true });
11
- };
12
- var __copyProps = (to, from, except, desc) => {
13
- if (from && typeof from === "object" || typeof from === "function") {
14
- for (let key of __getOwnPropNames(from))
15
- if (!__hasOwnProp.call(to, key) && key !== except)
16
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
- }
18
- return to;
19
- };
20
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
- // If the importer is in node compatibility mode or this is not an ESM
22
- // file that has been converted to a CommonJS file using a Babel-
23
- // compatible transform (i.e. "__esModule" has not been set), then set
24
- // "default" to the CommonJS "module.exports" for node compatibility.
25
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
- mod
27
- ));
28
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
-
30
- // src/index.ts
31
- var src_exports = {};
32
- __export(src_exports, {
33
- DEFAULT_OPTIONS: () => DEFAULT_OPTIONS,
34
- PLUGIN_IMAGE_COMPRESS_NAME: () => PLUGIN_IMAGE_COMPRESS_NAME,
35
- pluginImageCompress: () => pluginImageCompress
2
+ var __webpack_require__ = {};
3
+ (()=>{
4
+ __webpack_require__.n = (module)=>{
5
+ var getter = module && module.__esModule ? ()=>module['default'] : ()=>module;
6
+ __webpack_require__.d(getter, {
7
+ a: getter
8
+ });
9
+ return getter;
10
+ };
11
+ })();
12
+ (()=>{
13
+ __webpack_require__.d = (exports1, definition)=>{
14
+ for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
15
+ enumerable: true,
16
+ get: definition[key]
17
+ });
18
+ };
19
+ })();
20
+ (()=>{
21
+ __webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
22
+ })();
23
+ (()=>{
24
+ __webpack_require__.r = (exports1)=>{
25
+ if ('undefined' != typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
26
+ value: 'Module'
27
+ });
28
+ Object.defineProperty(exports1, '__esModule', {
29
+ value: true
30
+ });
31
+ };
32
+ })();
33
+ var __webpack_exports__ = {};
34
+ __webpack_require__.r(__webpack_exports__);
35
+ __webpack_require__.d(__webpack_exports__, {
36
+ pluginImageCompress: ()=>pluginImageCompress,
37
+ DEFAULT_OPTIONS: ()=>DEFAULT_OPTIONS,
38
+ PLUGIN_IMAGE_COMPRESS_NAME: ()=>PLUGIN_IMAGE_COMPRESS_NAME,
39
+ ImageMinimizerPlugin: ()=>ImageMinimizerPlugin
36
40
  });
37
- module.exports = __toCommonJS(src_exports);
38
- var import_node_assert2 = __toESM(require("assert"), 1);
39
-
40
- // src/minimizer.ts
41
- var import_node_buffer2 = require("buffer");
42
-
43
- // src/shared/codecs.ts
44
- var import_node_buffer = require("buffer");
45
- var import_image = require("@napi-rs/image");
46
- var import_svgo = __toESM(require("svgo"), 1);
47
- var jpegCodec = {
48
- handler(buf, options) {
49
- return (0, import_image.compressJpeg)(buf, options);
50
- },
51
- defaultOptions: {
52
- test: /\.(?:jpg|jpeg)$/
53
- }
41
+ const external_node_assert_namespaceObject = require("node:assert");
42
+ var external_node_assert_default = /*#__PURE__*/ __webpack_require__.n(external_node_assert_namespaceObject);
43
+ const external_node_buffer_namespaceObject = require("node:buffer");
44
+ const image_namespaceObject = require("@napi-rs/image");
45
+ const external_svgo_namespaceObject = require("svgo");
46
+ var external_svgo_default = /*#__PURE__*/ __webpack_require__.n(external_svgo_namespaceObject);
47
+ const jpegCodec = {
48
+ handler (buf, options) {
49
+ return (0, image_namespaceObject.compressJpeg)(buf, options);
50
+ },
51
+ defaultOptions: {
52
+ test: /\.(?:jpg|jpeg)$/
53
+ }
54
54
  };
55
- var pngCodec = {
56
- handler(buf, options) {
57
- return (0, import_image.pngQuantize)(buf, options);
58
- },
59
- defaultOptions: {
60
- test: /\.png$/
61
- }
55
+ const pngCodec = {
56
+ handler (buf, options) {
57
+ return (0, image_namespaceObject.pngQuantize)(buf, options);
58
+ },
59
+ defaultOptions: {
60
+ test: /\.png$/
61
+ }
62
62
  };
63
- var pngLosslessCodec = {
64
- handler(buf, options) {
65
- return (0, import_image.losslessCompressPng)(buf, options);
66
- },
67
- defaultOptions: {
68
- test: /\.png$/
69
- }
63
+ const pngLosslessCodec = {
64
+ handler (buf, options) {
65
+ return (0, image_namespaceObject.losslessCompressPng)(buf, options);
66
+ },
67
+ defaultOptions: {
68
+ test: /\.png$/
69
+ }
70
70
  };
71
- var icoCodec = {
72
- handler(buf) {
73
- return new import_image.Transformer(buf).ico();
74
- },
75
- defaultOptions: {
76
- test: /\.(?:ico|icon)$/
77
- }
71
+ const icoCodec = {
72
+ handler (buf) {
73
+ return new image_namespaceObject.Transformer(buf).ico();
74
+ },
75
+ defaultOptions: {
76
+ test: /\.(?:ico|icon)$/
77
+ }
78
+ };
79
+ const avifCodec = {
80
+ handler (buf, options) {
81
+ return new image_namespaceObject.Transformer(buf).avif(options);
82
+ },
83
+ defaultOptions: {
84
+ test: /\.avif$/
85
+ }
78
86
  };
79
- var svgCodec = {
80
- async handler(buf, options) {
81
- const result = import_svgo.default.optimize(buf.toString(), options);
82
- return import_node_buffer.Buffer.from(result.data);
83
- },
84
- defaultOptions: {
85
- test: /\.svg$/
86
- }
87
+ const svgCodec = {
88
+ async handler (buf, options) {
89
+ const result = external_svgo_default().optimize(buf.toString(), options);
90
+ return external_node_buffer_namespaceObject.Buffer.from(result.data);
91
+ },
92
+ defaultOptions: {
93
+ test: /\.svg$/
94
+ }
87
95
  };
88
- var codecs = {
89
- jpeg: jpegCodec,
90
- png: pngCodec,
91
- pngLossless: pngLosslessCodec,
92
- ico: icoCodec,
93
- svg: svgCodec
96
+ const codecs_codecs = {
97
+ jpeg: jpegCodec,
98
+ png: pngCodec,
99
+ pngLossless: pngLosslessCodec,
100
+ ico: icoCodec,
101
+ svg: svgCodec,
102
+ avif: avifCodec
94
103
  };
95
- var codecs_default = codecs;
96
-
97
- // src/minimizer.ts
98
- var IMAGE_MINIMIZER_PLUGIN_NAME = "@rsbuild/plugin-image-compress/minimizer";
99
- var ImageMinimizerPlugin = class {
100
- constructor(options) {
101
- this.name = IMAGE_MINIMIZER_PLUGIN_NAME;
102
- this.options = options;
103
- }
104
- async optimize(compiler, compilation, assets) {
105
- const cache = compilation.getCache(IMAGE_MINIMIZER_PLUGIN_NAME);
106
- const { RawSource } = compiler.webpack.sources;
107
- const { matchObject } = compiler.webpack.ModuleFilenameHelpers;
108
- const buildError = (error, file, context) => {
109
- const cause = error instanceof Error ? error : new Error();
110
- const message = file && context ? `"${file}" in "${context}" from Image Minimizer:
111
- ${cause.message}` : cause.message;
112
- const ret = new compiler.webpack.WebpackError(message);
113
- if (error instanceof Error) {
114
- ret.error = error;
115
- }
116
- return ret;
117
- };
118
- const codec = codecs_default[this.options.use];
119
- if (!codec) {
120
- compilation.errors.push(
121
- buildError(new Error(`Codec ${this.options.use} is not supported`))
122
- );
104
+ const codecs = codecs_codecs;
105
+ function _define_property(obj, key, value) {
106
+ if (key in obj) Object.defineProperty(obj, key, {
107
+ value: value,
108
+ enumerable: true,
109
+ configurable: true,
110
+ writable: true
111
+ });
112
+ else obj[key] = value;
113
+ return obj;
114
+ }
115
+ const IMAGE_MINIMIZER_PLUGIN_NAME = '@rsbuild/plugin-image-compress/minimizer';
116
+ class ImageMinimizerPlugin {
117
+ async optimize(compiler, compilation, assets) {
118
+ const cache = compilation.getCache(IMAGE_MINIMIZER_PLUGIN_NAME);
119
+ const { RawSource } = compiler.webpack.sources;
120
+ const { matchObject } = compiler.webpack.ModuleFilenameHelpers;
121
+ const buildError = (error, file, context)=>{
122
+ const cause = error instanceof Error ? error : new Error();
123
+ const message = file && context ? `"${file}" in "${context}" from Image Minimizer:\n${cause.message}` : cause.message;
124
+ const ret = new compiler.webpack.WebpackError(message);
125
+ if (error instanceof Error) ret.error = error;
126
+ return ret;
127
+ };
128
+ const codec = codecs[this.options.use];
129
+ if (!codec) compilation.errors.push(buildError(new Error(`Codec ${this.options.use} is not supported`)));
130
+ const opts = {
131
+ ...codec.defaultOptions,
132
+ ...this.options
133
+ };
134
+ const handleAsset = async (name)=>{
135
+ var _compilation_getAsset;
136
+ const info = null === (_compilation_getAsset = compilation.getAsset(name)) || void 0 === _compilation_getAsset ? void 0 : _compilation_getAsset.info;
137
+ const fileName = name.split('?')[0];
138
+ if ((null == info ? void 0 : info.minimized) || !matchObject(opts, fileName)) return;
139
+ const asset = compilation.getAsset(name);
140
+ if (!asset) return;
141
+ const { source: inputSource } = asset;
142
+ const eTag = cache.getLazyHashedEtag(inputSource);
143
+ const cacheItem = cache.getItemCache(name, eTag);
144
+ let result = await cacheItem.getPromise();
145
+ try {
146
+ if (!result) {
147
+ const input = inputSource.source();
148
+ const buf = await codec.handler('string' == typeof input ? external_node_buffer_namespaceObject.Buffer.from(input) : input, opts);
149
+ result = {
150
+ source: new RawSource(buf)
151
+ };
152
+ await cacheItem.storePromise(result);
153
+ }
154
+ compilation.updateAsset(name, result.source, {
155
+ minimized: true
156
+ });
157
+ } catch (error) {
158
+ compilation.errors.push(buildError(error, name, compiler.context));
159
+ }
160
+ };
161
+ const promises = Object.keys(assets).map((name)=>handleAsset(name));
162
+ await Promise.all(promises);
123
163
  }
124
- const opts = { ...codec.defaultOptions, ...this.options };
125
- const handleAsset = async (name) => {
126
- const info = compilation.getAsset(name)?.info;
127
- const fileName = name.split("?")[0];
128
- if (info?.minimized || !matchObject(opts, fileName)) {
129
- return;
130
- }
131
- const asset = compilation.getAsset(name);
132
- if (!asset) {
133
- return;
134
- }
135
- const { source: inputSource } = asset;
136
- const eTag = cache.getLazyHashedEtag(inputSource);
137
- const cacheItem = cache.getItemCache(name, eTag);
138
- let result = await cacheItem.getPromise();
139
- try {
140
- if (!result) {
141
- const input = inputSource.source();
142
- const buf = await codec.handler(import_node_buffer2.Buffer.from(input), opts);
143
- result = { source: new RawSource(buf) };
144
- await cacheItem.storePromise(result);
145
- }
146
- compilation.updateAsset(name, result.source, { minimized: true });
147
- } catch (error) {
148
- compilation.errors.push(buildError(error, name, compiler.context));
149
- }
150
- };
151
- const promises = Object.keys(assets).map((name) => handleAsset(name));
152
- await Promise.all(promises);
153
- }
154
- apply(compiler) {
155
- const handleCompilation = (compilation) => {
156
- compilation.hooks.processAssets.tapPromise(
157
- {
158
- name: this.name,
159
- stage: compiler.webpack.Compilation.PROCESS_ASSETS_STAGE_OPTIMIZE_SIZE,
160
- // @ts-expect-error unsupported by Rspack
161
- additionalAssets: true
162
- },
163
- (assets) => this.optimize(compiler, compilation, assets)
164
- );
165
- compilation.hooks.statsPrinter.tap(this.name, (stats) => {
166
- stats.hooks.print.for("asset.info.minimized").tap(
167
- "@rsbuild/plugin-image-compress",
168
- (minimized, { green, formatFlag }) => minimized && green && formatFlag ? green(formatFlag("minimized")) : ""
169
- );
170
- });
164
+ apply(compiler) {
165
+ const handleCompilation = (compilation)=>{
166
+ compilation.hooks.processAssets.tapPromise({
167
+ name: this.name,
168
+ stage: compiler.webpack.Compilation.PROCESS_ASSETS_STAGE_OPTIMIZE_SIZE,
169
+ additionalAssets: true
170
+ }, (assets)=>this.optimize(compiler, compilation, assets));
171
+ compilation.hooks.statsPrinter.tap(this.name, (stats)=>{
172
+ stats.hooks.print.for('asset.info.minimized').tap('@rsbuild/plugin-image-compress', (minimized, { green, formatFlag })=>minimized && green && formatFlag ? green(formatFlag('minimized')) : '');
173
+ });
174
+ };
175
+ compiler.hooks.compilation.tap(this.name, handleCompilation);
176
+ }
177
+ constructor(options){
178
+ _define_property(this, "name", IMAGE_MINIMIZER_PLUGIN_NAME);
179
+ _define_property(this, "options", void 0);
180
+ this.options = options;
181
+ }
182
+ }
183
+ const withDefaultOptions = (opt)=>{
184
+ const options = 'string' == typeof opt ? {
185
+ use: opt
186
+ } : opt;
187
+ const { defaultOptions } = codecs[options.use];
188
+ const ret = {
189
+ ...defaultOptions,
190
+ ...options
171
191
  };
172
- compiler.hooks.compilation.tap(this.name, handleCompilation);
173
- }
174
- };
175
-
176
- // src/shared/utils.ts
177
- var import_node_assert = __toESM(require("assert"), 1);
178
- var withDefaultOptions = (opt) => {
179
- const options = typeof opt === "string" ? { use: opt } : opt;
180
- const { defaultOptions } = codecs_default[options.use];
181
- const ret = { ...defaultOptions, ...options };
182
- (0, import_node_assert.default)("test" in ret);
183
- return ret;
192
+ external_node_assert_default()('test' in ret);
193
+ return ret;
184
194
  };
185
-
186
- // src/index.ts
187
- var DEFAULT_OPTIONS = ["jpeg", "png", "ico"];
188
- var castOptions = (args) => {
189
- const head = args[0];
190
- if (Array.isArray(head)) {
191
- return head;
192
- }
193
- const ret = [];
194
- for (const arg of args) {
195
- (0, import_node_assert2.default)(!Array.isArray(arg));
196
- ret.push(arg);
197
- }
198
- return ret;
195
+ const DEFAULT_OPTIONS = [
196
+ 'jpeg',
197
+ 'png',
198
+ 'ico'
199
+ ];
200
+ const castOptions = (args)=>{
201
+ const head = args[0];
202
+ if (Array.isArray(head)) return head;
203
+ const ret = [];
204
+ for (const arg of args){
205
+ external_node_assert_default()(!Array.isArray(arg));
206
+ ret.push(arg);
207
+ }
208
+ return ret;
199
209
  };
200
- var normalizeOptions = (options) => {
201
- const opts = options.length ? options : DEFAULT_OPTIONS;
202
- const normalized = opts.map((opt) => withDefaultOptions(opt));
203
- return normalized;
210
+ const normalizeOptions = (options)=>{
211
+ const opts = options.length ? options : DEFAULT_OPTIONS;
212
+ const normalized = opts.map((opt)=>withDefaultOptions(opt));
213
+ return normalized;
204
214
  };
205
- var PLUGIN_IMAGE_COMPRESS_NAME = "rsbuild:image-compress";
206
- var pluginImageCompress = (...args) => ({
207
- name: PLUGIN_IMAGE_COMPRESS_NAME,
208
- setup(api) {
209
- const opts = normalizeOptions(castOptions(args));
210
- api.modifyBundlerChain((chain, { isDev }) => {
211
- if (isDev) {
212
- return;
213
- }
214
- chain.optimization.minimize(true);
215
- for (const opt of opts) {
216
- chain.optimization.minimizer(`image-compress-${opt.use}`).use(ImageMinimizerPlugin, [opt]);
217
- }
215
+ const PLUGIN_IMAGE_COMPRESS_NAME = 'rsbuild:image-compress';
216
+ const pluginImageCompress = (...args)=>({
217
+ name: PLUGIN_IMAGE_COMPRESS_NAME,
218
+ setup (api) {
219
+ const opts = normalizeOptions(castOptions(args));
220
+ api.modifyBundlerChain((chain, { isDev })=>{
221
+ if (isDev) return;
222
+ chain.optimization.minimize(true);
223
+ for (const opt of opts)chain.optimization.minimizer(`image-compress-${opt.use}`).use(ImageMinimizerPlugin, [
224
+ opt
225
+ ]);
226
+ });
227
+ }
218
228
  });
219
- }
220
- });
221
- // Annotate the CommonJS export names for ESM import in node:
222
- 0 && (module.exports = {
223
- DEFAULT_OPTIONS,
224
- PLUGIN_IMAGE_COMPRESS_NAME,
225
- pluginImageCompress
229
+ exports.DEFAULT_OPTIONS = __webpack_exports__.DEFAULT_OPTIONS;
230
+ exports.ImageMinimizerPlugin = __webpack_exports__.ImageMinimizerPlugin;
231
+ exports.PLUGIN_IMAGE_COMPRESS_NAME = __webpack_exports__.PLUGIN_IMAGE_COMPRESS_NAME;
232
+ exports.pluginImageCompress = __webpack_exports__.pluginImageCompress;
233
+ for(var __webpack_i__ in __webpack_exports__)if (-1 === [
234
+ "DEFAULT_OPTIONS",
235
+ "ImageMinimizerPlugin",
236
+ "PLUGIN_IMAGE_COMPRESS_NAME",
237
+ "pluginImageCompress"
238
+ ].indexOf(__webpack_i__)) exports[__webpack_i__] = __webpack_exports__[__webpack_i__];
239
+ Object.defineProperty(exports, '__esModule', {
240
+ value: true
226
241
  });
package/dist/index.d.ts CHANGED
@@ -1,38 +1,13 @@
1
- import { RsbuildPlugin } from '@rsbuild/core';
2
- import { JpegCompressOptions, PngQuantOptions, PNGLosslessOptions } from '@napi-rs/image';
3
- import { Config } from 'svgo';
4
-
5
- type OneOrMany<T> = T | T[];
6
- interface CodecBaseOptions {
7
- jpeg: JpegCompressOptions;
8
- png: PngQuantOptions;
9
- pngLossless: PNGLosslessOptions;
10
- ico: Record<string, unknown>;
11
- svg: Config;
12
- }
13
- interface BaseCompressOptions<T extends Codecs> {
14
- use: T;
15
- test?: OneOrMany<RegExp>;
16
- include?: OneOrMany<RegExp>;
17
- exclude?: OneOrMany<RegExp>;
18
- }
19
- type FinalOptionCollection = {
20
- [K in Codecs]: BaseCompressOptions<K> & CodecBaseOptions[K];
21
- };
22
- type Codecs = keyof CodecBaseOptions;
23
- type OptionCollection = {
24
- [K in Codecs]: K | FinalOptionCollection[K];
25
- };
26
- type Options = OptionCollection[Codecs];
27
-
28
- type PluginImageCompressOptions = Options[];
29
- declare const DEFAULT_OPTIONS: Codecs[];
30
- interface IPluginImageCompress {
1
+ import type { RsbuildPlugin } from '@rsbuild/core';
2
+ import { ImageMinimizerPlugin } from './minimizer.js';
3
+ import type { Codecs, Options } from './types.js';
4
+ export type PluginImageCompressOptions = Options[];
5
+ export declare const DEFAULT_OPTIONS: Codecs[];
6
+ export interface IPluginImageCompress {
31
7
  (...options: Options[]): RsbuildPlugin;
32
8
  (options: Options[]): RsbuildPlugin;
33
9
  }
34
- declare const PLUGIN_IMAGE_COMPRESS_NAME = "rsbuild:image-compress";
10
+ export declare const PLUGIN_IMAGE_COMPRESS_NAME = "rsbuild:image-compress";
11
+ export { ImageMinimizerPlugin };
35
12
  /** Options enable by default: {@link DEFAULT_OPTIONS} */
36
- declare const pluginImageCompress: IPluginImageCompress;
37
-
38
- export { DEFAULT_OPTIONS, type IPluginImageCompress, PLUGIN_IMAGE_COMPRESS_NAME, type PluginImageCompressOptions, pluginImageCompress };
13
+ export declare const pluginImageCompress: IPluginImageCompress;
package/dist/index.js CHANGED
@@ -1,194 +1,187 @@
1
- // src/index.ts
2
- import assert2 from "node:assert";
3
-
4
- // src/minimizer.ts
5
- import { Buffer as Buffer2 } from "node:buffer";
6
-
7
- // src/shared/codecs.ts
8
- import { Buffer } from "node:buffer";
9
- import {
10
- Transformer,
11
- compressJpeg,
12
- losslessCompressPng,
13
- pngQuantize
14
- } from "@napi-rs/image";
15
- import svgo from "svgo";
16
- var jpegCodec = {
17
- handler(buf, options) {
18
- return compressJpeg(buf, options);
19
- },
20
- defaultOptions: {
21
- test: /\.(?:jpg|jpeg)$/
22
- }
1
+ import * as __WEBPACK_EXTERNAL_MODULE_node_assert_3e74d44e__ from "node:assert";
2
+ import * as __WEBPACK_EXTERNAL_MODULE_node_buffer_fb286294__ from "node:buffer";
3
+ import * as __WEBPACK_EXTERNAL_MODULE__napi_rs_image_caba25d1__ from "@napi-rs/image";
4
+ import * as __WEBPACK_EXTERNAL_MODULE_svgo__ from "svgo";
5
+ const jpegCodec = {
6
+ handler (buf, options) {
7
+ return (0, __WEBPACK_EXTERNAL_MODULE__napi_rs_image_caba25d1__.compressJpeg)(buf, options);
8
+ },
9
+ defaultOptions: {
10
+ test: /\.(?:jpg|jpeg)$/
11
+ }
23
12
  };
24
- var pngCodec = {
25
- handler(buf, options) {
26
- return pngQuantize(buf, options);
27
- },
28
- defaultOptions: {
29
- test: /\.png$/
30
- }
13
+ const pngCodec = {
14
+ handler (buf, options) {
15
+ return (0, __WEBPACK_EXTERNAL_MODULE__napi_rs_image_caba25d1__.pngQuantize)(buf, options);
16
+ },
17
+ defaultOptions: {
18
+ test: /\.png$/
19
+ }
31
20
  };
32
- var pngLosslessCodec = {
33
- handler(buf, options) {
34
- return losslessCompressPng(buf, options);
35
- },
36
- defaultOptions: {
37
- test: /\.png$/
38
- }
21
+ const pngLosslessCodec = {
22
+ handler (buf, options) {
23
+ return (0, __WEBPACK_EXTERNAL_MODULE__napi_rs_image_caba25d1__.losslessCompressPng)(buf, options);
24
+ },
25
+ defaultOptions: {
26
+ test: /\.png$/
27
+ }
39
28
  };
40
- var icoCodec = {
41
- handler(buf) {
42
- return new Transformer(buf).ico();
43
- },
44
- defaultOptions: {
45
- test: /\.(?:ico|icon)$/
46
- }
29
+ const icoCodec = {
30
+ handler (buf) {
31
+ return new __WEBPACK_EXTERNAL_MODULE__napi_rs_image_caba25d1__.Transformer(buf).ico();
32
+ },
33
+ defaultOptions: {
34
+ test: /\.(?:ico|icon)$/
35
+ }
47
36
  };
48
- var svgCodec = {
49
- async handler(buf, options) {
50
- const result = svgo.optimize(buf.toString(), options);
51
- return Buffer.from(result.data);
52
- },
53
- defaultOptions: {
54
- test: /\.svg$/
55
- }
37
+ const avifCodec = {
38
+ handler (buf, options) {
39
+ return new __WEBPACK_EXTERNAL_MODULE__napi_rs_image_caba25d1__.Transformer(buf).avif(options);
40
+ },
41
+ defaultOptions: {
42
+ test: /\.avif$/
43
+ }
56
44
  };
57
- var codecs = {
58
- jpeg: jpegCodec,
59
- png: pngCodec,
60
- pngLossless: pngLosslessCodec,
61
- ico: icoCodec,
62
- svg: svgCodec
45
+ const svgCodec = {
46
+ async handler (buf, options) {
47
+ const result = __WEBPACK_EXTERNAL_MODULE_svgo__["default"].optimize(buf.toString(), options);
48
+ return __WEBPACK_EXTERNAL_MODULE_node_buffer_fb286294__.Buffer.from(result.data);
49
+ },
50
+ defaultOptions: {
51
+ test: /\.svg$/
52
+ }
63
53
  };
64
- var codecs_default = codecs;
65
-
66
- // src/minimizer.ts
67
- var IMAGE_MINIMIZER_PLUGIN_NAME = "@rsbuild/plugin-image-compress/minimizer";
68
- var ImageMinimizerPlugin = class {
69
- constructor(options) {
70
- this.name = IMAGE_MINIMIZER_PLUGIN_NAME;
71
- this.options = options;
72
- }
73
- async optimize(compiler, compilation, assets) {
74
- const cache = compilation.getCache(IMAGE_MINIMIZER_PLUGIN_NAME);
75
- const { RawSource } = compiler.webpack.sources;
76
- const { matchObject } = compiler.webpack.ModuleFilenameHelpers;
77
- const buildError = (error, file, context) => {
78
- const cause = error instanceof Error ? error : new Error();
79
- const message = file && context ? `"${file}" in "${context}" from Image Minimizer:
80
- ${cause.message}` : cause.message;
81
- const ret = new compiler.webpack.WebpackError(message);
82
- if (error instanceof Error) {
83
- ret.error = error;
84
- }
85
- return ret;
86
- };
87
- const codec = codecs_default[this.options.use];
88
- if (!codec) {
89
- compilation.errors.push(
90
- buildError(new Error(`Codec ${this.options.use} is not supported`))
91
- );
54
+ const codecs_codecs = {
55
+ jpeg: jpegCodec,
56
+ png: pngCodec,
57
+ pngLossless: pngLosslessCodec,
58
+ ico: icoCodec,
59
+ svg: svgCodec,
60
+ avif: avifCodec
61
+ };
62
+ const codecs = codecs_codecs;
63
+ function _define_property(obj, key, value) {
64
+ if (key in obj) Object.defineProperty(obj, key, {
65
+ value: value,
66
+ enumerable: true,
67
+ configurable: true,
68
+ writable: true
69
+ });
70
+ else obj[key] = value;
71
+ return obj;
72
+ }
73
+ const IMAGE_MINIMIZER_PLUGIN_NAME = '@rsbuild/plugin-image-compress/minimizer';
74
+ class ImageMinimizerPlugin {
75
+ async optimize(compiler, compilation, assets) {
76
+ const cache = compilation.getCache(IMAGE_MINIMIZER_PLUGIN_NAME);
77
+ const { RawSource } = compiler.webpack.sources;
78
+ const { matchObject } = compiler.webpack.ModuleFilenameHelpers;
79
+ const buildError = (error, file, context)=>{
80
+ const cause = error instanceof Error ? error : new Error();
81
+ const message = file && context ? `"${file}" in "${context}" from Image Minimizer:\n${cause.message}` : cause.message;
82
+ const ret = new compiler.webpack.WebpackError(message);
83
+ if (error instanceof Error) ret.error = error;
84
+ return ret;
85
+ };
86
+ const codec = codecs[this.options.use];
87
+ if (!codec) compilation.errors.push(buildError(new Error(`Codec ${this.options.use} is not supported`)));
88
+ const opts = {
89
+ ...codec.defaultOptions,
90
+ ...this.options
91
+ };
92
+ const handleAsset = async (name)=>{
93
+ var _compilation_getAsset;
94
+ const info = null === (_compilation_getAsset = compilation.getAsset(name)) || void 0 === _compilation_getAsset ? void 0 : _compilation_getAsset.info;
95
+ const fileName = name.split('?')[0];
96
+ if ((null == info ? void 0 : info.minimized) || !matchObject(opts, fileName)) return;
97
+ const asset = compilation.getAsset(name);
98
+ if (!asset) return;
99
+ const { source: inputSource } = asset;
100
+ const eTag = cache.getLazyHashedEtag(inputSource);
101
+ const cacheItem = cache.getItemCache(name, eTag);
102
+ let result = await cacheItem.getPromise();
103
+ try {
104
+ if (!result) {
105
+ const input = inputSource.source();
106
+ const buf = await codec.handler('string' == typeof input ? __WEBPACK_EXTERNAL_MODULE_node_buffer_fb286294__.Buffer.from(input) : input, opts);
107
+ result = {
108
+ source: new RawSource(buf)
109
+ };
110
+ await cacheItem.storePromise(result);
111
+ }
112
+ compilation.updateAsset(name, result.source, {
113
+ minimized: true
114
+ });
115
+ } catch (error) {
116
+ compilation.errors.push(buildError(error, name, compiler.context));
117
+ }
118
+ };
119
+ const promises = Object.keys(assets).map((name)=>handleAsset(name));
120
+ await Promise.all(promises);
92
121
  }
93
- const opts = { ...codec.defaultOptions, ...this.options };
94
- const handleAsset = async (name) => {
95
- const info = compilation.getAsset(name)?.info;
96
- const fileName = name.split("?")[0];
97
- if (info?.minimized || !matchObject(opts, fileName)) {
98
- return;
99
- }
100
- const asset = compilation.getAsset(name);
101
- if (!asset) {
102
- return;
103
- }
104
- const { source: inputSource } = asset;
105
- const eTag = cache.getLazyHashedEtag(inputSource);
106
- const cacheItem = cache.getItemCache(name, eTag);
107
- let result = await cacheItem.getPromise();
108
- try {
109
- if (!result) {
110
- const input = inputSource.source();
111
- const buf = await codec.handler(Buffer2.from(input), opts);
112
- result = { source: new RawSource(buf) };
113
- await cacheItem.storePromise(result);
114
- }
115
- compilation.updateAsset(name, result.source, { minimized: true });
116
- } catch (error) {
117
- compilation.errors.push(buildError(error, name, compiler.context));
118
- }
119
- };
120
- const promises = Object.keys(assets).map((name) => handleAsset(name));
121
- await Promise.all(promises);
122
- }
123
- apply(compiler) {
124
- const handleCompilation = (compilation) => {
125
- compilation.hooks.processAssets.tapPromise(
126
- {
127
- name: this.name,
128
- stage: compiler.webpack.Compilation.PROCESS_ASSETS_STAGE_OPTIMIZE_SIZE,
129
- // @ts-expect-error unsupported by Rspack
130
- additionalAssets: true
131
- },
132
- (assets) => this.optimize(compiler, compilation, assets)
133
- );
134
- compilation.hooks.statsPrinter.tap(this.name, (stats) => {
135
- stats.hooks.print.for("asset.info.minimized").tap(
136
- "@rsbuild/plugin-image-compress",
137
- (minimized, { green, formatFlag }) => minimized && green && formatFlag ? green(formatFlag("minimized")) : ""
138
- );
139
- });
122
+ apply(compiler) {
123
+ const handleCompilation = (compilation)=>{
124
+ compilation.hooks.processAssets.tapPromise({
125
+ name: this.name,
126
+ stage: compiler.webpack.Compilation.PROCESS_ASSETS_STAGE_OPTIMIZE_SIZE,
127
+ additionalAssets: true
128
+ }, (assets)=>this.optimize(compiler, compilation, assets));
129
+ compilation.hooks.statsPrinter.tap(this.name, (stats)=>{
130
+ stats.hooks.print.for('asset.info.minimized').tap('@rsbuild/plugin-image-compress', (minimized, { green, formatFlag })=>minimized && green && formatFlag ? green(formatFlag('minimized')) : '');
131
+ });
132
+ };
133
+ compiler.hooks.compilation.tap(this.name, handleCompilation);
134
+ }
135
+ constructor(options){
136
+ _define_property(this, "name", IMAGE_MINIMIZER_PLUGIN_NAME);
137
+ _define_property(this, "options", void 0);
138
+ this.options = options;
139
+ }
140
+ }
141
+ const withDefaultOptions = (opt)=>{
142
+ const options = 'string' == typeof opt ? {
143
+ use: opt
144
+ } : opt;
145
+ const { defaultOptions } = codecs[options.use];
146
+ const ret = {
147
+ ...defaultOptions,
148
+ ...options
140
149
  };
141
- compiler.hooks.compilation.tap(this.name, handleCompilation);
142
- }
150
+ (0, __WEBPACK_EXTERNAL_MODULE_node_assert_3e74d44e__["default"])('test' in ret);
151
+ return ret;
143
152
  };
144
-
145
- // src/shared/utils.ts
146
- import assert from "node:assert";
147
- var withDefaultOptions = (opt) => {
148
- const options = typeof opt === "string" ? { use: opt } : opt;
149
- const { defaultOptions } = codecs_default[options.use];
150
- const ret = { ...defaultOptions, ...options };
151
- assert("test" in ret);
152
- return ret;
153
- };
154
-
155
- // src/index.ts
156
- var DEFAULT_OPTIONS = ["jpeg", "png", "ico"];
157
- var castOptions = (args) => {
158
- const head = args[0];
159
- if (Array.isArray(head)) {
160
- return head;
161
- }
162
- const ret = [];
163
- for (const arg of args) {
164
- assert2(!Array.isArray(arg));
165
- ret.push(arg);
166
- }
167
- return ret;
153
+ const DEFAULT_OPTIONS = [
154
+ 'jpeg',
155
+ 'png',
156
+ 'ico'
157
+ ];
158
+ const castOptions = (args)=>{
159
+ const head = args[0];
160
+ if (Array.isArray(head)) return head;
161
+ const ret = [];
162
+ for (const arg of args){
163
+ (0, __WEBPACK_EXTERNAL_MODULE_node_assert_3e74d44e__["default"])(!Array.isArray(arg));
164
+ ret.push(arg);
165
+ }
166
+ return ret;
168
167
  };
169
- var normalizeOptions = (options) => {
170
- const opts = options.length ? options : DEFAULT_OPTIONS;
171
- const normalized = opts.map((opt) => withDefaultOptions(opt));
172
- return normalized;
168
+ const normalizeOptions = (options)=>{
169
+ const opts = options.length ? options : DEFAULT_OPTIONS;
170
+ const normalized = opts.map((opt)=>withDefaultOptions(opt));
171
+ return normalized;
173
172
  };
174
- var PLUGIN_IMAGE_COMPRESS_NAME = "rsbuild:image-compress";
175
- var pluginImageCompress = (...args) => ({
176
- name: PLUGIN_IMAGE_COMPRESS_NAME,
177
- setup(api) {
178
- const opts = normalizeOptions(castOptions(args));
179
- api.modifyBundlerChain((chain, { isDev }) => {
180
- if (isDev) {
181
- return;
182
- }
183
- chain.optimization.minimize(true);
184
- for (const opt of opts) {
185
- chain.optimization.minimizer(`image-compress-${opt.use}`).use(ImageMinimizerPlugin, [opt]);
186
- }
173
+ const PLUGIN_IMAGE_COMPRESS_NAME = 'rsbuild:image-compress';
174
+ const pluginImageCompress = (...args)=>({
175
+ name: PLUGIN_IMAGE_COMPRESS_NAME,
176
+ setup (api) {
177
+ const opts = normalizeOptions(castOptions(args));
178
+ api.modifyBundlerChain((chain, { isDev })=>{
179
+ if (isDev) return;
180
+ chain.optimization.minimize(true);
181
+ for (const opt of opts)chain.optimization.minimizer(`image-compress-${opt.use}`).use(ImageMinimizerPlugin, [
182
+ opt
183
+ ]);
184
+ });
185
+ }
187
186
  });
188
- }
189
- });
190
- export {
191
- DEFAULT_OPTIONS,
192
- PLUGIN_IMAGE_COMPRESS_NAME,
193
- pluginImageCompress
194
- };
187
+ export { DEFAULT_OPTIONS, ImageMinimizerPlugin, PLUGIN_IMAGE_COMPRESS_NAME, pluginImageCompress };
@@ -0,0 +1,13 @@
1
+ import type { Rspack } from '@rsbuild/core';
2
+ import type { FinalOptions } from './types.js';
3
+ export declare const IMAGE_MINIMIZER_PLUGIN_NAME: "@rsbuild/plugin-image-compress/minimizer";
4
+ export interface MinimizedResult {
5
+ source: Rspack.sources.RawSource;
6
+ }
7
+ export declare class ImageMinimizerPlugin {
8
+ name: string;
9
+ options: FinalOptions;
10
+ constructor(options: FinalOptions);
11
+ optimize(compiler: Rspack.Compiler, compilation: Rspack.Compilation, assets: Record<string, Rspack.sources.Source>): Promise<void>;
12
+ apply(compiler: Rspack.Compiler): void;
13
+ }
@@ -0,0 +1,9 @@
1
+ import type { Codec, Codecs } from '../types.js';
2
+ export declare const jpegCodec: Codec<'jpeg'>;
3
+ export declare const pngCodec: Codec<'png'>;
4
+ export declare const pngLosslessCodec: Codec<'pngLossless'>;
5
+ export declare const icoCodec: Codec<'ico'>;
6
+ export declare const avifCodec: Codec<'avif'>;
7
+ export declare const svgCodec: Codec<'svg'>;
8
+ declare const codecs: Record<Codecs, Codec<any>>;
9
+ export default codecs;
@@ -0,0 +1,2 @@
1
+ import type { FinalOptions, Options } from '../types.js';
2
+ export declare const withDefaultOptions: (opt: Options) => FinalOptions;
@@ -0,0 +1,34 @@
1
+ import type { Buffer } from 'node:buffer';
2
+ import type { AvifConfig, JpegCompressOptions, PNGLosslessOptions, PngQuantOptions } from '@napi-rs/image';
3
+ import type { Config as SvgoConfig } from 'svgo';
4
+ export type OneOrMany<T> = T | T[];
5
+ export interface WebpTransformOptions {
6
+ quality?: number;
7
+ }
8
+ export interface CodecBaseOptions {
9
+ jpeg: JpegCompressOptions;
10
+ png: PngQuantOptions;
11
+ pngLossless: PNGLosslessOptions;
12
+ ico: Record<string, unknown>;
13
+ svg: SvgoConfig;
14
+ avif: AvifConfig;
15
+ }
16
+ export interface BaseCompressOptions<T extends Codecs> {
17
+ use: T;
18
+ test?: OneOrMany<RegExp>;
19
+ include?: OneOrMany<RegExp>;
20
+ exclude?: OneOrMany<RegExp>;
21
+ }
22
+ export type FinalOptionCollection = {
23
+ [K in Codecs]: BaseCompressOptions<K> & CodecBaseOptions[K];
24
+ };
25
+ export type FinalOptions = FinalOptionCollection[Codecs];
26
+ export interface Codec<T extends Codecs> {
27
+ handler: (buf: Buffer, options: CodecBaseOptions[T]) => Promise<Buffer>;
28
+ defaultOptions: Omit<FinalOptionCollection[T], 'use'>;
29
+ }
30
+ export type Codecs = keyof CodecBaseOptions;
31
+ export type OptionCollection = {
32
+ [K in Codecs]: K | FinalOptionCollection[K];
33
+ };
34
+ export type Options = OptionCollection[Codecs];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rsbuild/plugin-image-compress",
3
- "version": "1.0.2",
3
+ "version": "1.2.0",
4
4
  "repository": "https://github.com/rspack-contrib/rsbuild-plugin-image-compress",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -14,9 +14,16 @@
14
14
  "main": "./dist/index.js",
15
15
  "module": "./dist/index.mjs",
16
16
  "types": "./dist/index.d.ts",
17
- "files": [
18
- "dist"
19
- ],
17
+ "files": ["dist"],
18
+ "scripts": {
19
+ "build": "rslib build",
20
+ "dev": "rslib build --watch",
21
+ "lint": "biome check .",
22
+ "lint:write": "biome check . --write",
23
+ "prepare": "simple-git-hooks && npm run build",
24
+ "test": "playwright test",
25
+ "bump": "npx bumpp"
26
+ },
20
27
  "simple-git-hooks": {
21
28
  "pre-commit": "npx nano-staged"
22
29
  },
@@ -30,33 +37,27 @@
30
37
  "svgo": "^3.3.2"
31
38
  },
32
39
  "devDependencies": {
33
- "@biomejs/biome": "^1.8.3",
34
- "@playwright/test": "^1.45.3",
35
- "@rsbuild/core": "1.0.0-alpha.9",
36
- "@types/node": "^20.14.13",
40
+ "@biomejs/biome": "^1.9.4",
41
+ "@playwright/test": "^1.51.1",
42
+ "@rsbuild/core": "1.3.1",
43
+ "@rslib/core": "^0.6.1",
44
+ "@types/node": "^22.13.14",
37
45
  "nano-staged": "^0.8.0",
38
- "playwright": "^1.45.3",
39
- "simple-git-hooks": "^2.11.1",
40
- "tsup": "^8.2.3",
41
- "typescript": "^5.5.4"
46
+ "playwright": "^1.51.1",
47
+ "simple-git-hooks": "^2.12.1",
48
+ "typescript": "^5.8.2"
42
49
  },
43
50
  "peerDependencies": {
44
- "@rsbuild/core": "1.x || ^1.0.1-beta.0"
51
+ "@rsbuild/core": "1.x"
45
52
  },
46
53
  "peerDependenciesMeta": {
47
54
  "@rsbuild/core": {
48
55
  "optional": true
49
56
  }
50
57
  },
58
+ "packageManager": "pnpm@10.7.0",
51
59
  "publishConfig": {
52
60
  "access": "public",
53
61
  "registry": "https://registry.npmjs.org/"
54
- },
55
- "scripts": {
56
- "build": "tsup",
57
- "dev": "tsup --watch",
58
- "lint": "biome check .",
59
- "lint:write": "biome check . --write",
60
- "test": "playwright test"
61
62
  }
62
- }
63
+ }
package/dist/index.d.cts DELETED
@@ -1,38 +0,0 @@
1
- import { RsbuildPlugin } from '@rsbuild/core';
2
- import { JpegCompressOptions, PngQuantOptions, PNGLosslessOptions } from '@napi-rs/image';
3
- import { Config } from 'svgo';
4
-
5
- type OneOrMany<T> = T | T[];
6
- interface CodecBaseOptions {
7
- jpeg: JpegCompressOptions;
8
- png: PngQuantOptions;
9
- pngLossless: PNGLosslessOptions;
10
- ico: Record<string, unknown>;
11
- svg: Config;
12
- }
13
- interface BaseCompressOptions<T extends Codecs> {
14
- use: T;
15
- test?: OneOrMany<RegExp>;
16
- include?: OneOrMany<RegExp>;
17
- exclude?: OneOrMany<RegExp>;
18
- }
19
- type FinalOptionCollection = {
20
- [K in Codecs]: BaseCompressOptions<K> & CodecBaseOptions[K];
21
- };
22
- type Codecs = keyof CodecBaseOptions;
23
- type OptionCollection = {
24
- [K in Codecs]: K | FinalOptionCollection[K];
25
- };
26
- type Options = OptionCollection[Codecs];
27
-
28
- type PluginImageCompressOptions = Options[];
29
- declare const DEFAULT_OPTIONS: Codecs[];
30
- interface IPluginImageCompress {
31
- (...options: Options[]): RsbuildPlugin;
32
- (options: Options[]): RsbuildPlugin;
33
- }
34
- declare const PLUGIN_IMAGE_COMPRESS_NAME = "rsbuild:image-compress";
35
- /** Options enable by default: {@link DEFAULT_OPTIONS} */
36
- declare const pluginImageCompress: IPluginImageCompress;
37
-
38
- export { DEFAULT_OPTIONS, type IPluginImageCompress, PLUGIN_IMAGE_COMPRESS_NAME, type PluginImageCompressOptions, pluginImageCompress };