UNPKG

4.3 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3const esbuild_1 = require("esbuild");
4const webpack_sources_1 = require("webpack-sources");
5const ModuleFilenameHelpers_1 = require("webpack/lib/ModuleFilenameHelpers");
6// eslint-disable-next-line @typescript-eslint/no-var-requires
7const { version } = require('../package');
8const isJsFile = /\.js$/i;
9const isCssFile = /\.css$/i;
10const pluginName = 'esbuild-minify';
11const flatMap = (array, callback) => (
12// eslint-disable-next-line unicorn/no-array-callback-reference
13Array.prototype.concat(...array.map(callback)));
14class ESBuildMinifyPlugin {
15 constructor(options) {
16 this.options = { ...options };
17 const hasMinify = Object.keys(this.options).some(k => k.startsWith('minify'));
18 if (!hasMinify) {
19 this.options.minify = true;
20 }
21 }
22 apply(compiler) {
23 compiler.hooks.compilation.tap(pluginName, compilation => {
24 const meta = JSON.stringify({
25 name: 'esbuild-loader',
26 version,
27 options: this.options,
28 });
29 compilation.hooks.chunkHash.tap(pluginName, (_, hash) => hash.update(meta));
30 if ('processAssets' in compilation.hooks) {
31 const wp5Compilation = compilation;
32 wp5Compilation.hooks.processAssets.tapPromise({
33 name: pluginName,
34 stage: wp5Compilation.constructor.PROCESS_ASSETS_STAGE_OPTIMIZE_SIZE,
35 // @ts-expect-error
36 additionalAssets: true,
37 }, async (assets) => this.transformAssets(compilation, Object.keys(assets)));
38 wp5Compilation.hooks.statsPrinter.tap(pluginName, (statsPrinter) => {
39 statsPrinter.hooks.print
40 .for('asset.info.minimized')
41 .tap(pluginName, (minimized, { green, formatFlag }) => (minimized ?
42 green(formatFlag('minimized')) :
43 undefined));
44 });
45 }
46 else {
47 compilation.hooks.optimizeChunkAssets.tapPromise(pluginName, async (chunks) => this.transformAssets(compilation, flatMap(chunks, chunk => chunk.files)));
48 }
49 });
50 }
51 async transformAssets(compilation, assetNames) {
52 const { options: { devtool } } = compilation.compiler;
53 const sourcemap = (
54 // TODO: drop support for esbuild sourcemap in future so it all goes through WP API
55 this.options.sourcemap === undefined ?
56 devtool && devtool.includes('source-map') :
57 this.options.sourcemap);
58 const { css: minifyCss, include, exclude, ...transformOptions } = this.options;
59 const transforms = assetNames
60 .filter(assetName => ((isJsFile.test(assetName) ||
61 (minifyCss &&
62 isCssFile.test(assetName))) &&
63 ModuleFilenameHelpers_1.matchObject({ include, exclude }, assetName)))
64 .map((assetName) => [
65 assetName,
66 compilation.getAsset(assetName),
67 ])
68 .map(async ([assetName, { info, source: assetSource },]) => {
69 const assetIsCss = isCssFile.test(assetName);
70 const { source, map } = assetSource.sourceAndMap();
71 const result = await esbuild_1.transform(source.toString(), {
72 ...transformOptions,
73 loader: (assetIsCss ?
74 'css' :
75 transformOptions.loader),
76 sourcemap,
77 sourcefile: assetName,
78 });
79 compilation.updateAsset(assetName, (sourcemap &&
80 // CSS source-maps not supported yet https://github.com/evanw/esbuild/issues/519
81 !assetIsCss) ?
82 new webpack_sources_1.SourceMapSource(result.code || '', assetName, result.map, source === null || source === void 0 ? void 0 : source.toString(), map, true) :
83 new webpack_sources_1.RawSource(result.code || ''), {
84 ...info,
85 minimized: true,
86 });
87 });
88 if (transforms.length > 0) {
89 await Promise.all(transforms);
90 }
91 }
92}
93exports.default = ESBuildMinifyPlugin;