Skip to content

Add splitChunks optimization #12812

@petrovmiroslav

Description

@petrovmiroslav

Is your proposal related to a problem?

Using route-based code splitting causes css duplicate in chunks.

Steps to reproduce:

  1. Create simple app with create-react-app
  2. Use react-router-dom for client side routing
  3. Add one common component with local css.
  4. Add 2 pages, using the common component with style overwriting
  5. Run build command
  6. Check static folder
// /components/CommonPageHeader/CommonPageHeader.module.scss
.header {
  color: black;
}
// /components/CommonPageHeader/CommonPageHeader.tsx
import styles from "./CommonPageHeader.module.scss";
import { ReactNode } from "react";

export const CommonPageHeader = (props: {
  className: string;
  children: ReactNode;`your text`
}) => {
  const { className = "", children } = props;

  return <h1 className={`${styles.header} ${className}`}>{children}</h1>;
};
// /pages/Home/Home.module.scss
.greenHeader {
  color: green;
}
// /pages/Home/Home.tsx
import React from "react";
import { Link } from "react-router-dom";
import { CommonPageHeader } from "../../components/CommonPageHeader/CommonPageHeader";
import styles from "./Home.module.scss";

const Home = () => (
  <>
    <CommonPageHeader className={styles.greenHeader}>
      I'm a green header
    </CommonPageHeader>
    <Link to={"some-page"}>Some page</Link>
  </>
);
export default Home;

// /pages/SomePage/SomePage.module.scss
.redHeader {
  color: red;
}
// /pages/SomePage/SomePage.tsx
import React from "react";
import { Link } from "react-router-dom";
import { CommonPageHeader } from "../../components/CommonPageHeader/CommonPageHeader";
import styles from "./SomePage.module.scss";

const SomePage = () => {
  return (
    <>
      <CommonPageHeader className={styles.redHeader}>
        I'm a red header
      </CommonPageHeader>
      <Link to={"/"}>Home</Link>
    </>
  );
};
export default SomePage;

// index.tsx

import React, { Suspense } from "react";
import ReactDOM from "react-dom/client";
import { createBrowserRouter, RouterProvider } from "react-router-dom";

const Home = React.lazy(() => import("./pages/Home/Home"));
const SomePage = React.lazy(() => import("./pages/SomePage/SomePage"));

const router = createBrowserRouter([
  {
    path: "/",
    element: (
      <Suspense>
        <Home />
      </Suspense>
    ),
  },
  {
    path: "/some-page",
    element: (
      <Suspense>
        <SomePage />
      </Suspense>
    ),
  },
]);

const root = ReactDOM.createRoot(
  document.getElementById("root") as HTMLElement
);
root.render(
  <React.StrictMode>
    <RouterProvider router={router} />
  </React.StrictMode>
);

You get css chunks with duplicates and unexpected styles overwrites in production:

// /build/static/css/499.408c3ff0.chunk.css
.CommonPageHeader_header__eTauC {
    color: #000
}

.Home_greenHeader__YwF4H {
    color: green
}
// /build/static/css/136.855973ab.chunk.css
.CommonPageHeader_header__eTauC {
    color: #000
}

.SomePage_redHeader__a-I8c {
    color: red
}
2022-10-28.17.19.47.mov

Demo page

  1. Click to some page link
  2. Go back to home page

Repo

Describe the solution you'd like

Add splitChunks optimization to webpack.config.js.
For example:

module.exports = function (webpackEnv) {
  // ...
  return {
    // ...
    optimization: {
      // ...
      splitChunks: {
        cacheGroups: {
          commons: {
            name: "common",
            type: "css/mini-extract",
            chunks: "all",
            minChunks: 2,
            enforce: true,
            usedExports: true,
          },
        },
      },
    },
  };
};

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions