From df1d06b9c47692b357a6b69811c98a3156f2f231 Mon Sep 17 00:00:00 2001 From: Tim Neutkens Date: Sat, 22 Aug 2020 13:35:07 +0200 Subject: [PATCH] Add webpack 5 caching for css optimizer --- .../webpack/plugins/build-manifest-plugin.ts | 5 ++++- .../webpack/plugins/css-minimizer-plugin.ts | 20 ++++++++++++++++--- .../font-stylesheet-gathering-plugin.ts | 5 ++++- .../mini-css-extract-plugin/src/index.js | 3 ++- .../plugins/nextjs-ssr-module-cache.ts | 5 ++++- .../webpack/plugins/pages-manifest-plugin.ts | 5 ++++- .../webpack/plugins/react-loadable-plugin.ts | 7 ++++--- 7 files changed, 39 insertions(+), 11 deletions(-) diff --git a/packages/next/build/webpack/plugins/build-manifest-plugin.ts b/packages/next/build/webpack/plugins/build-manifest-plugin.ts index 54401f2ea9c25..01cacf64ad57d 100644 --- a/packages/next/build/webpack/plugins/build-manifest-plugin.ts +++ b/packages/next/build/webpack/plugins/build-manifest-plugin.ts @@ -1,6 +1,6 @@ import devalue from 'next/dist/compiled/devalue' import webpack, { Compiler, compilation as CompilationType } from 'webpack' -import { RawSource } from 'webpack-sources' +import sources from 'webpack-sources' import { BUILD_MANIFEST, CLIENT_STATIC_FILES_PATH, @@ -15,6 +15,9 @@ import { ampFirstEntryNamesMap } from './next-drop-client-page-plugin' import { Rewrite } from '../../../lib/load-custom-routes' import { getSortedRoutes } from '../../../next-server/lib/router/utils' +// @ts-ignore: TODO: remove ignore when webpack 5 is stable +const { RawSource } = webpack.sources || sources + const isWebpack5 = parseInt(webpack.version!) === 5 type DeepMutable = { -readonly [P in keyof T]: DeepMutable } diff --git a/packages/next/build/webpack/plugins/css-minimizer-plugin.ts b/packages/next/build/webpack/plugins/css-minimizer-plugin.ts index f9c0c4cea7b37..34ad34fbfe63d 100644 --- a/packages/next/build/webpack/plugins/css-minimizer-plugin.ts +++ b/packages/next/build/webpack/plugins/css-minimizer-plugin.ts @@ -1,6 +1,9 @@ import { process as minify } from 'cssnano-simple' import webpack from 'webpack' -import { RawSource, SourceMapSource } from 'webpack-sources' +import sources from 'webpack-sources' + +// @ts-ignore: TODO: remove ignore when webpack 5 is stable +const { RawSource, SourceMapSource } = webpack.sources || sources // https://github.com/NMFR/optimize-css-assets-webpack-plugin/blob/0a410a9bf28c7b0e81a3470a13748e68ca2f50aa/src/index.js#L20 const CSS_REGEX = /\.css(\?.*)?$/i @@ -50,6 +53,7 @@ export class CssMinimizerPlugin { apply(compiler: webpack.Compiler) { compiler.hooks.compilation.tap('CssMinimizerPlugin', (compilation: any) => { if (isWebpack5) { + const cache = compilation.getCache('CssMinimizerPlugin') compilation.hooks.processAssets.tapPromise( { name: 'CssMinimizerPlugin', @@ -62,9 +66,19 @@ export class CssMinimizerPlugin { files .filter((file) => CSS_REGEX.test(file)) .map(async (file) => { - const asset = compilation.assets[file] + const asset = assets[file] + + const etag = cache.getLazyHashedEtag(asset) + + const cachedResult = await cache.getPromise(file, etag) + if (cachedResult) { + assets[file] = cachedResult + return + } - assets[file] = await this.optimizeAsset(file, asset) + const result = await this.optimizeAsset(file, asset) + await cache.storePromise(file, etag, result) + assets[file] = result }) ) } diff --git a/packages/next/build/webpack/plugins/font-stylesheet-gathering-plugin.ts b/packages/next/build/webpack/plugins/font-stylesheet-gathering-plugin.ts index 2101c313adf86..5b8517cf0cff2 100644 --- a/packages/next/build/webpack/plugins/font-stylesheet-gathering-plugin.ts +++ b/packages/next/build/webpack/plugins/font-stylesheet-gathering-plugin.ts @@ -1,6 +1,6 @@ import webpack, { compilation as CompilationType, Compiler } from 'webpack' import { namedTypes } from 'ast-types' -import { RawSource } from 'webpack-sources' +import sources from 'webpack-sources' import { getFontDefinitionFromNetwork, FontManifest, @@ -11,6 +11,9 @@ import postcss from 'postcss' import minifier from 'cssnano-simple' import { OPTIMIZED_FONT_PROVIDERS } from '../../../next-server/lib/constants' +// @ts-ignore: TODO: remove ignore when webpack 5 is stable +const { RawSource } = webpack.sources || sources + const isWebpack5 = parseInt(webpack.version!) === 5 async function minifyCss(css: string): Promise { diff --git a/packages/next/build/webpack/plugins/mini-css-extract-plugin/src/index.js b/packages/next/build/webpack/plugins/mini-css-extract-plugin/src/index.js index ef2b1241b1874..4f0ece4826a26 100644 --- a/packages/next/build/webpack/plugins/mini-css-extract-plugin/src/index.js +++ b/packages/next/build/webpack/plugins/mini-css-extract-plugin/src/index.js @@ -6,7 +6,8 @@ import sources from 'webpack-sources' import CssDependency from './CssDependency' import CssModule from './CssModule' -const { ConcatSource, SourceMapSource, OriginalSource } = sources +const { ConcatSource, SourceMapSource, OriginalSource } = + webpack.sources || sources const { Template, util: { createHash }, diff --git a/packages/next/build/webpack/plugins/nextjs-ssr-module-cache.ts b/packages/next/build/webpack/plugins/nextjs-ssr-module-cache.ts index ec00655b23beb..9953a65780a61 100644 --- a/packages/next/build/webpack/plugins/nextjs-ssr-module-cache.ts +++ b/packages/next/build/webpack/plugins/nextjs-ssr-module-cache.ts @@ -1,9 +1,12 @@ import webpack from 'webpack' -import { RawSource } from 'webpack-sources' +import sources from 'webpack-sources' import { join, relative, dirname } from 'path' import getRouteFromEntrypoint from '../../../next-server/server/get-route-from-entrypoint' const SSR_MODULE_CACHE_FILENAME = 'ssr-module-cache.js' +// @ts-ignore: TODO: remove ignore when webpack 5 is stable +const { RawSource } = webpack.sources || sources + // By default webpack keeps initialized modules per-module. // This means that if you have 2 entrypoints loaded into the same app // they will *not* share the same instance diff --git a/packages/next/build/webpack/plugins/pages-manifest-plugin.ts b/packages/next/build/webpack/plugins/pages-manifest-plugin.ts index 94557901c74ba..fbd5b332c4ded 100644 --- a/packages/next/build/webpack/plugins/pages-manifest-plugin.ts +++ b/packages/next/build/webpack/plugins/pages-manifest-plugin.ts @@ -1,10 +1,13 @@ import webpack, { Compiler, Plugin } from 'webpack' -import { RawSource } from 'webpack-sources' +import sources from 'webpack-sources' import { PAGES_MANIFEST } from '../../../next-server/lib/constants' import getRouteFromEntrypoint from '../../../next-server/server/get-route-from-entrypoint' export type PagesManifest = { [page: string]: string } +// @ts-ignore: TODO: remove ignore when webpack 5 is stable +const { RawSource } = webpack.sources || sources + const isWebpack5 = parseInt(webpack.version!) === 5 // This plugin creates a pages-manifest.json from page entrypoints. diff --git a/packages/next/build/webpack/plugins/react-loadable-plugin.ts b/packages/next/build/webpack/plugins/react-loadable-plugin.ts index de62a8600daa1..bb6810c094dfe 100644 --- a/packages/next/build/webpack/plugins/react-loadable-plugin.ts +++ b/packages/next/build/webpack/plugins/react-loadable-plugin.ts @@ -28,6 +28,9 @@ import webpack, { } from 'webpack' import sources from 'webpack-sources' +// @ts-ignore: TODO: remove ignore when webpack 5 is stable +const { RawSource } = webpack.sources || sources + const isWebpack5 = parseInt(webpack.version!) === 5 function getModulesIterable(compilation: any, chunk: any) { @@ -110,9 +113,7 @@ export class ReactLoadablePlugin { createAssets(compiler: any, compilation: any, assets: any) { const manifest = buildManifest(compiler, compilation) // @ts-ignore: TODO: remove when webpack 5 is stable - assets[this.filename] = new (webpack.sources || sources).RawSource( - JSON.stringify(manifest, null, 2) - ) + assets[this.filename] = new RawSource(JSON.stringify(manifest, null, 2)) return assets }