1 | "use strict";
|
2 |
|
3 | const path = require("path");
|
4 |
|
5 | const worker = require("./worker");
|
6 |
|
7 | const schema = require("./loader-options.json");
|
8 |
|
9 | const {
|
10 | isAbsoluteURL
|
11 | } = require("./utils.js");
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
17 |
|
18 |
|
19 |
|
20 |
|
21 |
|
22 |
|
23 |
|
24 |
|
25 |
|
26 |
|
27 |
|
28 |
|
29 |
|
30 |
|
31 |
|
32 | async function loader(content) {
|
33 |
|
34 | if (this._module && this._module.buildMeta && this._module.buildMeta.imageMinimizerPluginInfo && (this._module.buildMeta.imageMinimizerPluginInfo.minimized || this._module.buildMeta.imageMinimizerPluginInfo.generated)) {
|
35 | return content;
|
36 | }
|
37 |
|
38 |
|
39 | const options = this.getOptions(
|
40 |
|
41 | schema);
|
42 | const callback = this.async();
|
43 | const {
|
44 | generator,
|
45 | minimizer,
|
46 | severityError
|
47 | } = options;
|
48 |
|
49 | if (!minimizer && !generator) {
|
50 | callback(new Error("Not configured 'minimizer' or 'generator' options, please setup them"));
|
51 | return;
|
52 | }
|
53 |
|
54 | let transformer = minimizer;
|
55 | let parsedQuery;
|
56 |
|
57 | if (this.resourceQuery.length > 0) {
|
58 | parsedQuery = new URLSearchParams(this.resourceQuery);
|
59 |
|
60 | if (parsedQuery.has("as")) {
|
61 | if (!generator) {
|
62 | callback(new Error("Please specify the 'generator' option to use 'as' query param for generation purposes."));
|
63 | return;
|
64 | }
|
65 |
|
66 | const as = parsedQuery.get("as");
|
67 | const presets = generator.filter(item => item.preset === as);
|
68 |
|
69 | if (presets.length > 1) {
|
70 | callback(new Error("Found several identical pereset names, the 'preset' option should be unique"));
|
71 | return;
|
72 | }
|
73 |
|
74 | if (presets.length === 0) {
|
75 | callback(new Error(`Can't find '${as}' preset in the 'generator' option`));
|
76 | return;
|
77 | }
|
78 |
|
79 | [transformer] = presets;
|
80 | }
|
81 | }
|
82 |
|
83 | if (!transformer) {
|
84 | callback(null, content);
|
85 | return;
|
86 | }
|
87 |
|
88 | const isAbsolute = isAbsoluteURL(this.resourcePath);
|
89 | const filename = isAbsolute ? this.resourcePath : path.relative(this.rootContext, this.resourcePath);
|
90 | const minifyOptions =
|
91 |
|
92 | {
|
93 | input: content,
|
94 | filename,
|
95 | severityError,
|
96 | transformer,
|
97 | generateFilename:
|
98 |
|
99 | this._compilation.getAssetPath.bind(this._compilation)
|
100 | };
|
101 | const output = await worker(minifyOptions);
|
102 |
|
103 | if (output.errors && output.errors.length > 0) {
|
104 | output.errors.forEach(error => {
|
105 | this.emitError(error);
|
106 | });
|
107 | callback(null, content);
|
108 | return;
|
109 | }
|
110 |
|
111 | if (output.warnings && output.warnings.length > 0) {
|
112 | output.warnings.forEach(warning => {
|
113 | this.emitWarning(warning);
|
114 | });
|
115 | }
|
116 |
|
117 |
|
118 | if (this._module && this._module.resourceResolveData && this._module.resourceResolveData.encodedContent) {
|
119 | const isBase64 = /^base64$/i.test(this._module.resourceResolveData.encoding);
|
120 | this._module.resourceResolveData.encodedContent = isBase64 ? output.data.toString("base64") : encodeURIComponent(output.data.toString("utf-8")).replace(/[!'()*]/g, character => `%${
|
121 | /** @type {number} */
|
122 | character.codePointAt(0).toString(16)}`);
|
123 | } else {
|
124 | let query = this.resourceQuery;
|
125 |
|
126 | if (parsedQuery) {
|
127 |
|
128 | const stringifiedParsedQuery = parsedQuery.toString();
|
129 | query = stringifiedParsedQuery.length > 0 ? `?${stringifiedParsedQuery}` : "";
|
130 | parsedQuery.delete("as");
|
131 | }
|
132 |
|
133 |
|
134 | this.resourcePath = isAbsolute ? output.filename : path.join(this.rootContext, output.filename);
|
135 | this.resourceQuery = query;
|
136 |
|
137 | if (this._module && !this._module.matchResource) {
|
138 | this._module.matchResource = `${output.filename}${query}`;
|
139 | }
|
140 | }
|
141 |
|
142 |
|
143 | if (this._module) {
|
144 | this._module.buildMeta = { ...this._module.buildMeta,
|
145 | imageMinimizerPluginInfo: output.info
|
146 | };
|
147 | }
|
148 |
|
149 | callback(null, output.data);
|
150 | }
|
151 |
|
152 | loader.raw = true;
|
153 | module.exports = loader; |
\ | No newline at end of file |