Skip to content

Commit b20f9b0

Browse files
refactor: code
1 parent 0c81417 commit b20f9b0

File tree

8 files changed

+507
-373
lines changed

8 files changed

+507
-373
lines changed

package-lock.json

Lines changed: 276 additions & 228 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
"lint": "npm-run-all -l -p \"lint:**\"",
2828
"test:only": "cross-env NODE_ENV=test jest",
2929
"test:watch": "npm run test:only -- --watch",
30-
"test:coverage": "npm run test:only -- --collectCoverageFrom=\"src/**/*.js\" --coverage",
30+
"test:coverage": "npm run test:only -- --collectCoverageFrom=\"src/**/{!(utils),}.js\" --coverage",
3131
"pretest": "npm run lint",
3232
"test": "npm run test:coverage",
3333
"prepare": "husky install && npm run build",

src/index.js

Lines changed: 28 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ import * as cssNanoPackageJson from 'cssnano/package.json';
77
import pLimit from 'p-limit';
88
import Worker from 'jest-worker';
99

10+
import { CssMinimizerPluginCssnano } from './utils';
11+
1012
import * as schema from './options.json';
1113
import { minify as minifyFn } from './minify';
1214

@@ -20,10 +22,8 @@ class CssMinimizerPlugin {
2022
});
2123

2224
const {
23-
minify,
24-
minimizerOptions = {
25-
preset: 'default',
26-
},
25+
minify = CssMinimizerPluginCssnano,
26+
minimizerOptions,
2727
test = /\.css(\?.*)?$/i,
2828
warningsFilter = () => true,
2929
parallel = true,
@@ -282,21 +282,31 @@ class CssMinimizerPlugin {
282282
}
283283

284284
const minifyFns =
285-
typeof this.options.minify === 'undefined'
286-
? // eslint-disable-next-line no-undefined
287-
undefined
288-
: typeof this.options.minify === 'function'
285+
typeof this.options.minify === 'function'
289286
? [this.options.minify]
290287
: this.options.minify;
291288
const minimizerOptions = {
292289
name,
293290
input,
294291
inputSourceMap,
295-
minimizerOptions: this.options.minimizerOptions,
296-
minify: this.options.minify,
297292
};
298293

299-
if (!minifyFns) {
294+
let warnings = [];
295+
let i = 0;
296+
297+
this.options.minimizerOptions = Array.isArray(
298+
this.options.minimizerOptions
299+
)
300+
? this.options.minimizerOptions
301+
: [this.options.minimizerOptions];
302+
303+
for await (const minifyFunc of minifyFns) {
304+
minimizerOptions.minify = minifyFunc;
305+
minimizerOptions.minimizerOptions = this.options.minimizerOptions[
306+
i
307+
];
308+
i += 1;
309+
300310
try {
301311
output = await (getWorker
302312
? getWorker().transform(serialize(minimizerOptions))
@@ -316,51 +326,14 @@ class CssMinimizerPlugin {
316326

317327
return;
318328
}
319-
} else {
320-
let warnings = [];
321-
let i = 0;
322-
323-
this.options.minimizerOptions = Array.isArray(
324-
this.options.minimizerOptions
325-
)
326-
? this.options.minimizerOptions
327-
: [this.options.minimizerOptions];
328-
329-
for await (const minifyFunc of minifyFns) {
330-
minimizerOptions.minify = minifyFunc;
331-
minimizerOptions.minimizerOptions = this.options.minimizerOptions[
332-
i
333-
];
334-
i += 1;
335-
336-
try {
337-
output = await (getWorker
338-
? getWorker().transform(serialize(minimizerOptions))
339-
: minifyFn(minimizerOptions));
340-
} catch (error) {
341-
compilation.errors.push(
342-
CssMinimizerPlugin.buildError(
343-
error,
344-
name,
345-
compilation.requestShortener,
346-
inputSourceMap &&
347-
CssMinimizerPlugin.isSourceMap(inputSourceMap)
348-
? new SourceMapConsumer(inputSourceMap)
349-
: null
350-
)
351-
);
352-
353-
return;
354-
}
355-
356-
minimizerOptions.input = output.code;
357-
minimizerOptions.inputSourceMap = output.map;
358-
warnings = warnings.concat(output.warnings);
359-
}
360329

361-
output.warnings = warnings;
330+
minimizerOptions.input = output.code;
331+
minimizerOptions.inputSourceMap = output.map;
332+
warnings = warnings.concat(output.warnings);
362333
}
363334

335+
output.warnings = warnings;
336+
364337
if (output.map) {
365338
output.source = new SourceMapSource(
366339
output.code,
@@ -478,4 +451,6 @@ class CssMinimizerPlugin {
478451
}
479452
}
480453

454+
CssMinimizerPlugin.cssnano = CssMinimizerPluginCssnano;
455+
481456
export default CssMinimizerPlugin;

src/minify.js

Lines changed: 9 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
const cssnano = require('cssnano');
21
/*
32
* We bring to the line here, because when passing result from the worker,
43
* the warning.toString is replaced with native Object.toString
@@ -7,34 +6,6 @@ function warningsToString(warnings) {
76
return warnings.map((i) => i.toString());
87
}
98

10-
async function load(module) {
11-
let exports;
12-
13-
try {
14-
// eslint-disable-next-line import/no-dynamic-require, global-require
15-
exports = require(module);
16-
17-
return exports;
18-
} catch (requireError) {
19-
let importESM;
20-
21-
try {
22-
// eslint-disable-next-line no-new-func
23-
importESM = new Function('id', 'return import(id);');
24-
} catch (e) {
25-
importESM = null;
26-
}
27-
28-
if (requireError.code === 'ERR_REQUIRE_ESM' && importESM) {
29-
exports = await importESM(module);
30-
31-
return exports.default;
32-
}
33-
34-
throw requireError;
35-
}
36-
}
37-
389
const minify = async (options) => {
3910
const {
4011
name,
@@ -44,70 +15,17 @@ const minify = async (options) => {
4415
minify: minifyFn,
4516
} = options;
4617

47-
if (minifyFn) {
48-
const result = await minifyFn(
49-
{ [name]: input },
50-
inputSourceMap,
51-
minimizerOptions
52-
);
53-
54-
return {
55-
// TODO remove `css` in future major release
56-
code: result.code || result.css,
57-
map: result.map,
58-
warnings: warningsToString(result.warnings || []),
59-
};
60-
}
61-
62-
const postcssOptions = {
63-
to: name,
64-
from: name,
65-
...minimizerOptions.processorOptions,
66-
};
67-
68-
if (typeof postcssOptions.parser === 'string') {
69-
try {
70-
postcssOptions.parser = await load(postcssOptions.parser);
71-
} catch (error) {
72-
throw new Error(
73-
`Loading PostCSS "${postcssOptions.parser}" parser failed: ${error.message}\n\n(@${name})`
74-
);
75-
}
76-
}
77-
78-
if (typeof postcssOptions.stringifier === 'string') {
79-
try {
80-
postcssOptions.stringifier = await load(postcssOptions.stringifier);
81-
} catch (error) {
82-
throw new Error(
83-
`Loading PostCSS "${postcssOptions.stringifier}" stringifier failed: ${error.message}\n\n(@${name})`
84-
);
85-
}
86-
}
87-
88-
if (typeof postcssOptions.syntax === 'string') {
89-
try {
90-
postcssOptions.syntax = await load(postcssOptions.syntax);
91-
} catch (error) {
92-
throw new Error(
93-
`Loading PostCSS "${postcssOptions.syntax}" syntax failed: ${error.message}\n\n(@${name})`
94-
);
95-
}
96-
}
97-
98-
if (inputSourceMap) {
99-
postcssOptions.map = {
100-
annotation: false,
101-
prev: inputSourceMap,
102-
};
103-
}
104-
105-
const result = await cssnano.process(input, postcssOptions, minimizerOptions);
18+
const result = await minifyFn(
19+
{ [name]: input },
20+
inputSourceMap,
21+
minimizerOptions
22+
);
10623

10724
return {
108-
code: result.css,
109-
map: result.map && result.map.toString(),
110-
warnings: warningsToString(result.warnings()),
25+
// TODO remove `css` in future major release
26+
code: result.code || result.css,
27+
map: result.map,
28+
warnings: warningsToString(result.warnings || []),
11129
};
11230
};
11331

src/utils.js

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
async function CssMinimizerPluginCssnano(
2+
data,
3+
inputSourceMap,
4+
minimizerOptions = { preset: 'default' }
5+
) {
6+
const [[name, input]] = Object.entries(data);
7+
const postcssOptions = {
8+
to: name,
9+
from: name,
10+
...minimizerOptions.processorOptions,
11+
};
12+
13+
if (typeof postcssOptions.parser === 'string') {
14+
try {
15+
postcssOptions.parser = await load(postcssOptions.parser);
16+
} catch (error) {
17+
throw new Error(
18+
`Loading PostCSS "${postcssOptions.parser}" parser failed: ${error.message}\n\n(@${name})`
19+
);
20+
}
21+
}
22+
23+
if (typeof postcssOptions.stringifier === 'string') {
24+
try {
25+
postcssOptions.stringifier = await load(postcssOptions.stringifier);
26+
} catch (error) {
27+
throw new Error(
28+
`Loading PostCSS "${postcssOptions.stringifier}" stringifier failed: ${error.message}\n\n(@${name})`
29+
);
30+
}
31+
}
32+
33+
if (typeof postcssOptions.syntax === 'string') {
34+
try {
35+
postcssOptions.syntax = await load(postcssOptions.syntax);
36+
} catch (error) {
37+
throw new Error(
38+
`Loading PostCSS "${postcssOptions.syntax}" syntax failed: ${error.message}\n\n(@${name})`
39+
);
40+
}
41+
}
42+
43+
if (inputSourceMap) {
44+
postcssOptions.map = {
45+
annotation: false,
46+
prev: inputSourceMap,
47+
};
48+
}
49+
50+
// eslint-disable-next-line global-require
51+
const cssnano = require('cssnano');
52+
const result = await cssnano.process(input, postcssOptions, minimizerOptions);
53+
54+
return {
55+
code: result.css,
56+
map: result.map && result.map.toString(),
57+
warnings: result.warnings().map(String),
58+
};
59+
60+
async function load(module) {
61+
let exports;
62+
63+
try {
64+
// eslint-disable-next-line import/no-dynamic-require, global-require
65+
exports = require(module);
66+
67+
return exports;
68+
} catch (requireError) {
69+
let importESM;
70+
71+
try {
72+
// eslint-disable-next-line no-new-func
73+
importESM = new Function('id', 'return import(id);');
74+
} catch (e) {
75+
importESM = null;
76+
}
77+
78+
if (requireError.code === 'ERR_REQUIRE_ESM' && importESM) {
79+
exports = await importESM(module);
80+
81+
return exports.default;
82+
}
83+
84+
throw requireError;
85+
}
86+
}
87+
}
88+
89+
// eslint-disable-next-line import/prefer-default-export
90+
export { CssMinimizerPluginCssnano };

test/__snapshots__/minify-option.test.js.snap

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,22 @@ exports[`"minify" option should work if minify is array && minimizerOptions is o
5656

5757
exports[`"minify" option should work if minify is array && minimizerOptions is object: warning 1`] = `Array []`;
5858

59+
exports[`"minify" option should work with "CssMinimizerPlugin.cssnano" and parser option as "String": entry.js.map 1`] = `"{\\"version\\":3,\\"sources\\":[\\"webpack:///webpack/bootstrap\\",\\"webpack:///webpack/runtime/define property getters\\",\\"webpack:///webpack/runtime/hasOwnProperty shorthand\\",\\"webpack:///webpack/runtime/make namespace object\\",\\"webpack:///./sugarss.js\\"],\\"names\\":[],\\"mappings\\":\\";;UAAA;UACA;;;;;WCDA;WACA;WACA;WACA;WACA,wCAAwC,yCAAyC;WACjF;WACA;WACA,E;;;;;WCPA,wF;;;;;WCAA;WACA;WACA;WACA,sDAAsD,kBAAkB;WACxE;WACA,+CAA+C,cAAc;WAC7D,E;;;;;;;;;;;;ACNO\\",\\"file\\":\\"entry.js\\",\\"sourcesContent\\":[\\"// The require scope\\\\nvar __webpack_require__ = {};\\\\n\\\\n\\",\\"// define getter functions for harmony exports\\\\n__webpack_require__.d = (exports, definition) => {\\\\n\\\\tfor(var key in definition) {\\\\n\\\\t\\\\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\\\\n\\\\t\\\\t\\\\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\\\\n\\\\t\\\\t}\\\\n\\\\t}\\\\n};\\",\\"__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))\\",\\"// define __esModule on exports\\\\n__webpack_require__.r = (exports) => {\\\\n\\\\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\\\\n\\\\t\\\\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\\\\n\\\\t}\\\\n\\\\tObject.defineProperty(exports, '__esModule', { value: true });\\\\n};\\",\\"export const foo = 'foo';\\\\n\\"],\\"sourceRoot\\":\\"\\"}"`;
60+
61+
exports[`"minify" option should work with "CssMinimizerPlugin.cssnano" and parser option as "String": index.sss 1`] = `"a{color:#000}"`;
62+
63+
exports[`"minify" option should work with "CssMinimizerPlugin.cssnano": assets 1`] = `
64+
Object {
65+
"foo.css": "body{font-weight:700;color:red}body a{text-align:center}
66+
/*# sourceMappingURL=foo.css.map*/",
67+
"foo.css.map": "{\\"version\\":3,\\"sources\\":[\\"webpack:///./sourcemap/bar.scss\\",\\"webpack:///./sourcemap/foo.scss\\"],\\"names\\":[],\\"mappings\\":\\"AAAA,KACE,eAAiB,CCEjB,SDFiB,CCCnB,OAGI,iBAAkB\\",\\"file\\":\\"foo.css\\",\\"sourcesContent\\":[\\"body {\\\\n font-weight: bold;\\\\n}\\",\\"@import 'bar';\\\\n\\\\nbody {\\\\n color: red;\\\\n a {\\\\n text-align: center;\\\\n }\\\\n}\\"],\\"sourceRoot\\":\\"\\"}",
68+
}
69+
`;
70+
71+
exports[`"minify" option should work with "CssMinimizerPlugin.cssnano": error 1`] = `Array []`;
72+
73+
exports[`"minify" option should work with "CssMinimizerPlugin.cssnano": warning 1`] = `Array []`;
74+
5975
exports[`"minify" option should work with "clean-css" minifier: assets 1`] = `
6076
Object {
6177
"foo.css": "body{color:red}a{color:#00f}",

0 commit comments

Comments
 (0)