From 652b0328ab6d11942c8fe77de71b7187cbc1c802 Mon Sep 17 00:00:00 2001 From: Hiroki Osame Date: Mon, 7 Aug 2023 15:44:18 +0900 Subject: [PATCH] fix(plugin): only minimize when used as minimizer --- .github/workflows/test.yml | 2 +- src/plugin.ts | 35 ++++++++++++------- tests/specs/plugin.ts | 69 ++++++++++++++++++++++++++++++++++++-- 3 files changed, 90 insertions(+), 16 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index b064950b..318984e7 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -35,7 +35,7 @@ jobs: - name: Test env: - NODE_OPTIONS: --openssl-legacy-provider + NODE_OPTIONS: --openssl-legacy-provider run: pnpm test - name: Test Node.js v16 diff --git a/src/plugin.ts b/src/plugin.ts index d01f988d..698dca8c 100644 --- a/src/plugin.ts +++ b/src/plugin.ts @@ -5,7 +5,7 @@ import { } from 'webpack-sources'; import webpack4 from 'webpack'; import webpack5 from 'webpack5'; -import { matchObject } from 'webpack/lib/ModuleFilenameHelpers.js'; +import ModuleFilenameHelpers from 'webpack/lib/ModuleFilenameHelpers.js'; import { version } from '../package.json'; import type { EsbuildPluginOptions } from './types.js'; @@ -47,7 +47,7 @@ const transformAssets = async ( isJsFile.test(asset.name) || (minifyCss && isCssFile.test(asset.name)) ) - && matchObject( + && ModuleFilenameHelpers.matchObject( { include, exclude }, asset.name, ) @@ -129,17 +129,7 @@ export default function EsbuildPlugin( const transform = implementation?.transform ?? defaultEsbuildTransform; - const hasGranularMinificationConfig = ( - 'minifyIdentifiers' in options - || 'minifySyntax' in options - || 'minifyWhitespace' in options - ); - - if (!hasGranularMinificationConfig) { - options.minify = true; - } - - return { + const pluginInstance = { apply(compiler: Compiler) { if (!('format' in options)) { const { target } = compiler.options; @@ -162,6 +152,23 @@ export default function EsbuildPlugin( } } + /** + * Enable minification by default if used in the minimizer array + * unless further specified in the options + */ + const usedAsMinimizer = compiler.options.optimization?.minimizer?.includes?.(pluginInstance); + if ( + usedAsMinimizer + && !( + 'minify' in options + || 'minifyWhitespace' in options + || 'minifyIdentifiers' in options + || 'minifySyntax' in options + ) + ) { + options.minify = compiler.options.optimization?.minimize; + } + compiler.hooks.compilation.tap(pluginName, (compilation) => { const meta = JSON.stringify({ name: 'esbuild-loader', @@ -230,4 +237,6 @@ export default function EsbuildPlugin( }); }, }; + + return pluginInstance; } diff --git a/tests/specs/plugin.ts b/tests/specs/plugin.ts index b4cb14d8..98c4b16d 100644 --- a/tests/specs/plugin.ts +++ b/tests/specs/plugin.ts @@ -9,7 +9,7 @@ import { configureMiniCssExtractPlugin, } from '../utils.js'; import * as fixtures from '../fixtures.js'; -import type { EsbuildPluginOptions } from '#esbuild-loader'; +import { EsbuildPlugin, type EsbuildPluginOptions } from '#esbuild-loader'; const assertMinified = (code: string) => { expect(code).not.toMatch(/\s{2,}/); @@ -23,7 +23,72 @@ export default testSuite(({ describe }, webpack: typeof webpack4 | typeof webpac const webpackIs4 = isWebpack4(webpack); describe('Plugin', ({ test, describe }) => { - describe('Minify JS', ({ test }) => { + describe('Minify JS', ({ test, describe }) => { + describe('should not minify by default', ({ test }) => { + test('minimizer', async () => { + const built = await build( + fixtures.minification, + (config) => { + config.optimization = { + minimize: false, + minimizer: [ + new EsbuildPlugin(), + ], + }; + }, + webpack, + ); + + expect(built.stats.hasWarnings()).toBe(false); + expect(built.stats.hasErrors()).toBe(false); + + const exportedFunction = built.require('/dist/'); + expect(exportedFunction('hello world')).toBe('hello world'); + expect(exportedFunction.toString()).toMatch(/\s{2,}/); + }); + + test('plugin', async () => { + const built = await build( + fixtures.minification, + (config) => { + config.plugins?.push(new EsbuildPlugin()); + }, + webpack, + ); + + expect(built.stats.hasWarnings()).toBe(false); + expect(built.stats.hasErrors()).toBe(false); + + const exportedFunction = built.require('/dist/'); + expect(exportedFunction('hello world')).toBe('hello world'); + expect(exportedFunction.toString()).toMatch(/\s{2,}/); + }); + + test('plugin with minimize enabled', async () => { + const built = await build( + fixtures.minification, + (config) => { + config.optimization = { + minimize: true, + + // Remove Terser + minimizer: [], + }; + + config.plugins?.push(new EsbuildPlugin()); + }, + webpack, + ); + + expect(built.stats.hasWarnings()).toBe(false); + expect(built.stats.hasErrors()).toBe(false); + + const exportedFunction = built.require('/dist/'); + expect(exportedFunction('hello world')).toBe('hello world'); + expect(exportedFunction.toString()).toMatch(/\s{2,}/); + }); + }); + test('minify', async () => { const built = await build( fixtures.minification,