You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

动态导入为何触发两次网络请求?基于Create React App的Webpack问题

Why does Webpack split my lazy-loaded Swiper component into two chunks, and how to fix it in Create React App?

I've created a custom Swiper.js wrapper file to handle importing Swiper's CSS and exporting the React component:

// Swiper.js
import swiperStyles from '!!raw-loader!swiper/dist/css/swiper.min.css';
const swiperElement = document.createElement('style');
swiperElement.innerHTML = swiperStyles;
document.head.append(swiperElement);
export { default } from 'react-id-swiper';

When I lazy-load this component using const Swiper = import('./Swiper'), Webpack splits the code into two network requests: one vendor chunk containing the CSS and React component code, and another small chunk just with the logic to insert the <style> tag into the document head. I'm using Create React App—why is this happening, and how can I avoid the extra chunk?


Why Webpack is splitting the chunk

Webpack's code-splitting logic is triggering this split due to how you've structured the module:

  • The !!raw-loader! syntax bypasses CRA's default CSS loaders, treating the CSS as a raw string instead of processing it as standard bundled CSS.
  • Your export { default } from 'react-id-swiper' line creates a direct reference to the external component that Webpack sees as separable from the style-injection code. Since the style-injection logic is tiny and self-contained, Webpack splits it into a separate chunk in an attempt to optimize loading—even though it creates an unnecessary extra request here.

How to fix the extra chunk

Here are practical, CRA-friendly solutions to eliminate the split:

Option 1: Merge style injection with component import

Restructure your Swiper.js to keep the style logic and component export as a single, cohesive module. This tells Webpack not to split them:

// Swiper.js
import swiperStyles from '!!raw-loader!swiper/dist/css/swiper.min.css';
import SwiperComponent from 'react-id-swiper';

// Inject styles when the module loads
const swiperElement = document.createElement('style');
swiperElement.innerHTML = swiperStyles;
document.head.append(swiperElement);

export default SwiperComponent;

Option 2: Use CRA's default CSS handling (simplest approach)

If you don't need manual <style> tag injection, let CRA handle the CSS normally. This aligns with CRA's best practices and eliminates the split entirely:

// Swiper.js
import 'swiper/dist/css/swiper.min.css';
export { default } from 'react-id-swiper';

CRA's Webpack config will bundle the CSS into your main stylesheet (or a dedicated CSS chunk) automatically, no extra requests required.

Option 3: Tweak Webpack config (advanced)

If you must keep the raw-loader approach, you can adjust Webpack's chunk-splitting rules. Since CRA hides its config by default, you have two paths:

  • Eject: Run npm run eject to expose the Webpack config, then modify the splitChunks settings (e.g., raise the minSize threshold) so the tiny style-injection chunk gets merged into the vendor chunk. Note that ejecting is irreversible.
  • Use react-app-rewired: This tool lets you override the Webpack config without ejecting. You can add a rule to disable splitting for your custom Swiper.js module or adjust chunk-sizing rules.

内容的提问来源于stack exchange,提问作者wa4_tasty_elephant

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 08:43:01