UNPKG

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