From 59522c80147e8fa166d035088ba079f2d70f4d71 Mon Sep 17 00:00:00 2001 From: Nicola Molinari Date: Fri, 10 Mar 2023 22:14:29 +0100 Subject: [PATCH] refactor(mc-scripts): manually group some vendor chunks --- .changeset/lazy-donuts-share.md | 5 +++ .../mc-scripts/src/commands/build-vite.ts | 2 + .../create-webpack-config-for-development.ts | 11 +++-- .../create-webpack-config-for-production.ts | 4 ++ .../mc-scripts/src/config/optimizations.ts | 42 +++++++++++++++++++ 5 files changed, 58 insertions(+), 6 deletions(-) create mode 100644 .changeset/lazy-donuts-share.md create mode 100644 packages/mc-scripts/src/config/optimizations.ts diff --git a/.changeset/lazy-donuts-share.md b/.changeset/lazy-donuts-share.md new file mode 100644 index 0000000000..fbec90c0ea --- /dev/null +++ b/.changeset/lazy-donuts-share.md @@ -0,0 +1,5 @@ +--- +'@commercetools-frontend/mc-scripts': patch +--- + +Manually group some vendor chunks diff --git a/packages/mc-scripts/src/commands/build-vite.ts b/packages/mc-scripts/src/commands/build-vite.ts index 7bea7f31a6..fcef7b7384 100644 --- a/packages/mc-scripts/src/commands/build-vite.ts +++ b/packages/mc-scripts/src/commands/build-vite.ts @@ -5,6 +5,7 @@ import fs from 'fs-extra'; import { build, type Plugin } from 'vite'; import { packageLocation as applicationStaticAssetsPath } from '@commercetools-frontend/assets'; import { generateTemplate } from '@commercetools-frontend/mc-html-template'; +import { manualChunks } from '../config/optimizations'; import paths from '../config/paths'; import pluginDynamicBaseAssetsGlobals from '../vite-plugins/vite-plugin-dynamic-base-assets-globals'; import pluginSvgr from '../vite-plugins/vite-plugin-svgr'; @@ -40,6 +41,7 @@ async function run() { // NOTE that after the build, Vite will write the `index.html` (template) // at the `/public/public/index.html` location. See `fs.renameSync` below. input: paths.appIndexHtml, + output: { manualChunks }, }, }, server: { diff --git a/packages/mc-scripts/src/config/create-webpack-config-for-development.ts b/packages/mc-scripts/src/config/create-webpack-config-for-development.ts index 831bfa3c06..4ef98a3547 100644 --- a/packages/mc-scripts/src/config/create-webpack-config-for-development.ts +++ b/packages/mc-scripts/src/config/create-webpack-config-for-development.ts @@ -11,10 +11,11 @@ import type { import LocalHtmlWebpackPlugin from '../webpack-plugins/local-html-webpack-plugin'; import createPostcssConfig from './create-postcss-config'; import hasJsxRuntime from './has-jsx-runtime'; +// https://babeljs.io/blog/2017/09/11/zero-config-with-babel-macros import momentLocalesToKeep from /* preval */ './moment-locales'; +import { webpackCacheGroups } from './optimizations'; import paths from './paths'; import vendorsToTranspile from './vendors-to-transpile'; -// https://babeljs.io/blog/2017/09/11/zero-config-with-babel-macros const defaultToggleFlags: TWebpackConfigToggleFlagsForDevelopment = { generateIndexHtml: true, @@ -69,17 +70,15 @@ function createWebpackConfigForDevelopment( // https://medium.com/webpack/webpack-4-code-splitting-chunk-graph-and-the-splitchunks-optimization-be739a861366 // https://medium.com/webpack/webpack-4-mode-and-optimization-5423a6bc597a optimization: { - // Automatically split vendor and commons - // https://twitter.com/wSokra/status/969633336732905474 - splitChunks: { - chunks: 'all', - }, // Keep the runtime chunk separated to enable long term caching // https://twitter.com/wSokra/status/969679223278505985 // https://github.com/facebook/create-react-app/issues/5358 runtimeChunk: { name: 'runtime', }, + splitChunks: { + cacheGroups: webpackCacheGroups, + }, moduleIds: 'named', chunkIds: 'deterministic', }, diff --git a/packages/mc-scripts/src/config/create-webpack-config-for-production.ts b/packages/mc-scripts/src/config/create-webpack-config-for-production.ts index 05eb695029..fb7aa57086 100644 --- a/packages/mc-scripts/src/config/create-webpack-config-for-production.ts +++ b/packages/mc-scripts/src/config/create-webpack-config-for-production.ts @@ -18,6 +18,7 @@ import createPostcssConfig from './create-postcss-config'; import hasJsxRuntime from './has-jsx-runtime'; // https://babeljs.io/blog/2017/09/11/zero-config-with-babel-macros import momentLocalesToKeep from /* preval */ './moment-locales'; +import { webpackCacheGroups } from './optimizations'; import paths from './paths'; import vendorsToTranspile from './vendors-to-transpile'; @@ -126,6 +127,9 @@ function createWebpackConfigForProduction( runtimeChunk: { name: 'runtime', }, + splitChunks: { + cacheGroups: webpackCacheGroups, + }, moduleIds: 'named', chunkIds: 'deterministic', }, diff --git a/packages/mc-scripts/src/config/optimizations.ts b/packages/mc-scripts/src/config/optimizations.ts new file mode 100644 index 0000000000..07635d98cb --- /dev/null +++ b/packages/mc-scripts/src/config/optimizations.ts @@ -0,0 +1,42 @@ +// Dependencies to be split/grouped into separate chunks. +// This is useful to reduce the main bundle size and have more +// dedicated caching strategy for specific chunks. +// https://webpack.js.org/plugins/split-chunks-plugin/ +// https://rollupjs.org/configuration-options/#output-manualchunks +const manualChunks = { + 'apollo-client': ['@apollo/client'], + 'core-js-pure': ['core-js-pure'], + 'commercetools-uikit-icons': ['@commercetools-uikit/icons'], + moment: ['moment', 'moment-timezone'], + react: [ + 'react', + 'react-dom', + 'react-router', + 'react-router-dom', + 'react-intl', + ], + redux: [ + '@reduxjs/toolkit', + 'redux', + 'react-redux', + 'redux-logger', + 'redux-thunk', + ], + 'sentry-browser': ['@sentry/browser'], +}; + +const webpackCacheGroups = Object.entries(manualChunks).reduce( + (previousChunks, [chunkName, vendors]) => { + return { + ...previousChunks, + [chunkName]: { + test: new RegExp(`[\\/]node_modules[\\/](${vendors.join('|')})[\\/]`), + name: chunkName, + chunks: 'all', + }, + }; + }, + {} +); + +export { manualChunks, webpackCacheGroups };