Skip to content

Commit

Permalink
simplify webpack config minify usage
Browse files Browse the repository at this point in the history
  • Loading branch information
slorber committed Feb 2, 2024
1 parent 0510a3c commit 9662027
Show file tree
Hide file tree
Showing 4 changed files with 109 additions and 99 deletions.
9 changes: 3 additions & 6 deletions packages/docusaurus/src/webpack/base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ import {
getCustomizableJSLoader,
getStyleLoaders,
getCustomBabelConfigFilePath,
getMinimizer,
} from './utils';
import {getMinimizer} from './minification';
import {loadThemeAliases, loadDocusaurusAliases} from './aliases';
import type {Configuration} from 'webpack';
import type {Props} from '@docusaurus/types';
Expand Down Expand Up @@ -66,8 +66,7 @@ export async function createBaseConfig({
} = props;
const totalPages = routesPaths.length;
const isProd = process.env.NODE_ENV === 'production';
const minimizeEnabled = minify && isProd && !isServer;
const useSimpleCssMinifier = process.env.USE_SIMPLE_CSS_MINIFIER === 'true';
const minimizeEnabled = minify && isProd;

const fileLoaderUtils = getFileLoaderUtils();

Expand Down Expand Up @@ -160,9 +159,7 @@ export async function createBaseConfig({
// Only minimize client bundle in production because server bundle is only
// used for static site generation
minimize: minimizeEnabled,
minimizer: minimizeEnabled
? getMinimizer(useSimpleCssMinifier)
: undefined,
minimizer: minimizeEnabled ? getMinimizer() : undefined,
splitChunks: isServer
? false
: {
Expand Down
102 changes: 102 additions & 0 deletions packages/docusaurus/src/webpack/minification.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

import TerserPlugin from 'terser-webpack-plugin';
import CssMinimizerPlugin from 'css-minimizer-webpack-plugin';
import type {CustomOptions, CssNanoOptions} from 'css-minimizer-webpack-plugin';
import type {WebpackPluginInstance} from 'webpack';

// See https://github.com/webpack-contrib/terser-webpack-plugin#parallel
function getTerserParallel() {
let terserParallel: boolean | number = true;
if (process.env.TERSER_PARALLEL === 'false') {
terserParallel = false;
} else if (
process.env.TERSER_PARALLEL &&
parseInt(process.env.TERSER_PARALLEL, 10) > 0
) {
terserParallel = parseInt(process.env.TERSER_PARALLEL, 10);
}
return terserParallel;
}

function getJsMinifierPlugin() {
return new TerserPlugin({
parallel: getTerserParallel(),
terserOptions: {
parse: {
// We want uglify-js to parse ecma 8 code. However, we don't want it
// to apply any minification steps that turns valid ecma 5 code
// into invalid ecma 5 code. This is why the 'compress' and 'output'
// sections only apply transformations that are ecma 5 safe
// https://github.com/facebook/create-react-app/pull/4234
ecma: 2020,
},
compress: {
ecma: 5,
},
mangle: {
safari10: true,
},
output: {
ecma: 5,
comments: false,
// Turned on because emoji and regex is not minified properly using
// default. See https://github.com/facebook/create-react-app/issues/2488
ascii_only: true,
},
},
});
}

function getAdvancedCssMinifier() {
// Using the array syntax to add 2 minimizers
// see https://github.com/webpack-contrib/css-minimizer-webpack-plugin#array
return new CssMinimizerPlugin<[CssNanoOptions, CustomOptions]>({
minimizerOptions: [
// CssNano options
{
preset: require.resolve('@docusaurus/cssnano-preset'),
},
// CleanCss options
{
inline: false,
level: {
1: {
all: false,
removeWhitespace: true,
},
2: {
all: true,
restructureRules: true,
removeUnusedAtRules: false,
},
},
},
],
minify: [
CssMinimizerPlugin.cssnanoMinify,
CssMinimizerPlugin.cleanCssMinify,
],
});
}

export function getMinimizer(): WebpackPluginInstance[] {
// This is an historical env variable to opt-out of the advanced minifier
// Sometimes there's a bug in it and people are happy to disable it
const useSimpleCssMinifier = process.env.USE_SIMPLE_CSS_MINIFIER === 'true';

const minimizer: WebpackPluginInstance[] = [getJsMinifierPlugin()];

if (useSimpleCssMinifier) {
minimizer.push(new CssMinimizerPlugin());
} else {
minimizer.push(getAdvancedCssMinifier());
}

return minimizer;
}
4 changes: 3 additions & 1 deletion packages/docusaurus/src/webpack/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@ export default async function createServerConfig(params: {
const baseConfig = await createBaseConfig({
props,
isServer: true,
minify: true, // TODO is it worth it to minify server bundle??? benchmark

// Minification of server bundle reduces size but doubles bundle time :/
minify: false,
});

const outputFilename = 'server.bundle.js';
Expand Down
93 changes: 1 addition & 92 deletions packages/docusaurus/src/webpack/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,8 @@ import {
customizeArray,
customizeObject,
} from 'webpack-merge';
import webpack, {
type Configuration,
type RuleSetRule,
type WebpackPluginInstance,
} from 'webpack';
import TerserPlugin from 'terser-webpack-plugin';
import CssMinimizerPlugin from 'css-minimizer-webpack-plugin';
import webpack, {type Configuration, type RuleSetRule} from 'webpack';
import formatWebpackMessages from 'react-dev-utils/formatWebpackMessages';
import type {CustomOptions, CssNanoOptions} from 'css-minimizer-webpack-plugin';
import type {TransformOptions} from '@babel/core';
import type {
Plugin,
Expand Down Expand Up @@ -418,87 +411,3 @@ export async function getHttpsConfig(): Promise<
}
return isHttps;
}

// See https://github.com/webpack-contrib/terser-webpack-plugin#parallel
function getTerserParallel() {
let terserParallel: boolean | number = true;
if (process.env.TERSER_PARALLEL === 'false') {
terserParallel = false;
} else if (
process.env.TERSER_PARALLEL &&
parseInt(process.env.TERSER_PARALLEL, 10) > 0
) {
terserParallel = parseInt(process.env.TERSER_PARALLEL, 10);
}
return terserParallel;
}

export function getMinimizer(
useSimpleCssMinifier = false,
): WebpackPluginInstance[] {
const minimizer: WebpackPluginInstance[] = [
new TerserPlugin({
parallel: getTerserParallel(),
terserOptions: {
parse: {
// We want uglify-js to parse ecma 8 code. However, we don't want it
// to apply any minification steps that turns valid ecma 5 code
// into invalid ecma 5 code. This is why the 'compress' and 'output'
// sections only apply transformations that are ecma 5 safe
// https://github.com/facebook/create-react-app/pull/4234
ecma: 2020,
},
compress: {
ecma: 5,
},
mangle: {
safari10: true,
},
output: {
ecma: 5,
comments: false,
// Turned on because emoji and regex is not minified properly using
// default. See https://github.com/facebook/create-react-app/issues/2488
ascii_only: true,
},
},
}),
];
if (useSimpleCssMinifier) {
minimizer.push(new CssMinimizerPlugin());
} else {
minimizer.push(
// Using the array syntax to add 2 minimizers
// see https://github.com/webpack-contrib/css-minimizer-webpack-plugin#array
new CssMinimizerPlugin<[CssNanoOptions, CustomOptions]>({
minimizerOptions: [
// CssNano options
{
preset: require.resolve('@docusaurus/cssnano-preset'),
},
// CleanCss options
{
inline: false,
level: {
1: {
all: false,
removeWhitespace: true,
},
2: {
all: true,
restructureRules: true,
removeUnusedAtRules: false,
},
},
},
],
minify: [
CssMinimizerPlugin.cssnanoMinify,
CssMinimizerPlugin.cleanCssMinify,
],
}),
);
}

return minimizer;
}

0 comments on commit 9662027

Please sign in to comment.