1 |
|
2 |
|
3 |
|
4 | const browserslist = require("browserslist");
|
5 |
|
6 | const { readFileSync } = require("fs");
|
7 | const path = require("path");
|
8 |
|
9 |
|
10 | class WebpackObsoletePlugin {
|
11 | constructor(options) {
|
12 | const defaultOptions = {
|
13 | name: "obsolete",
|
14 | };
|
15 |
|
16 | this.options = {
|
17 | ...defaultOptions,
|
18 | ...options,
|
19 | };
|
20 | }
|
21 |
|
22 | |
23 |
|
24 |
|
25 |
|
26 |
|
27 |
|
28 | indent(str, size) {
|
29 | return " ".repeat(size) + str.replace(/\n/g, `$&${" ".repeat(size)}`);
|
30 | }
|
31 |
|
32 | stringify(json, indent = 2) {
|
33 | return JSON.stringify(json, null, indent)
|
34 | .replace(/"/g, `'`)
|
35 | .replace(/'(\w+)':/g, "$1:");
|
36 | }
|
37 |
|
38 | filterObject(object, callback, thisArg) {
|
39 | const ret = {};
|
40 |
|
41 | Object.entries(object).forEach(([key, value]) => {
|
42 | if (callback.call(thisArg, value, key, object)) {
|
43 | ret[key] = value;
|
44 | }
|
45 | });
|
46 | return ret;
|
47 | }
|
48 |
|
49 |
|
50 | apply(compiler) {
|
51 | compiler.hooks.compilation.tap(this.constructor.name, (compilation) => {
|
52 | compilation.hooks.processAssets.tap(
|
53 | {
|
54 | name: this.constructor.name,
|
55 | stage: compiler.webpack.Compilation.PROCESS_ASSETS_STAGE_PRE_PROCESS,
|
56 | },
|
57 | () => {
|
58 | const chunk = compilation.addChunk("obsolete");
|
59 | chunk.id = "obsolete";
|
60 | chunk.ids = ["obsolete"];
|
61 |
|
62 | for (const entrypoint of compilation.entrypoints.values()) {
|
63 | if (entrypoint.pushChunk(chunk)) {
|
64 | chunk.addGroup(entrypoint);
|
65 | }
|
66 | }
|
67 | const tmpFile = "obsolete.js";
|
68 | chunk.files.add(tmpFile);
|
69 | const { RawSource } = compiler.webpack.sources;
|
70 | const obsoleteFileContent = this.composeCode(this.options);
|
71 |
|
72 | compilation.assets[tmpFile] = new RawSource(obsoleteFileContent);
|
73 | compilation.updateAsset(tmpFile, (v) => v);
|
74 | }
|
75 | );
|
76 | });
|
77 | }
|
78 |
|
79 | composeCode(context) {
|
80 | const slimOptions = this.filterObject(context, (value) => !["", null, undefined].includes(value));
|
81 | const fileContent = readFileSync(path.resolve(__dirname, "obsolete.js"), {
|
82 | encoding: "utf-8",
|
83 | });
|
84 | return (
|
85 | fileContent +
|
86 | [
|
87 | this.indent(`(function() {`, 0),
|
88 | this.indent(`'use strict';`, 2),
|
89 | this.indent(`obsolete(${this.stringify(browserslist())},${this.stringify(slimOptions)});`, 2),
|
90 | this.indent(`})();\n`, 0),
|
91 | ].join("\n")
|
92 | );
|
93 | }
|
94 | }
|
95 | module.exports = WebpackObsoletePlugin;
|