使用CRACO自定义 Webpack 配置

1、为什么要用 CRACO?

默认情况下,CRA 的 Webpack 配置是隐藏的,如果你需要修改 Webpack,比如:

✅ CDN配置

✅ 配置 alias(路径别名)

✅ 修改 Less/Sass 变量

✅ 添加 Babel 插件

✅ 优化 Webpack 构建(如 SplitChunks、CDN 加载)

✅ 支持 Tailwind CSS

✅ 移动端适配启用 PostCSS + px 转 rem

如果不用 CRACO,你必须运行 yarn eject / npm run eject,但这会暴露 CRA 内部所有配置,导致维护成本增加。因此,CRACO 允许在不 eject 的情况下修改 Webpack 配置。

2、craco.config.js 是什么?从哪里来的?

1️⃣ craco.config.js 是什么?

craco.config.js 是 CRACO(Create React App Configuration Override) 的配置文件。

它用于修改 Create React App(CRA)的 Webpack 配置,无需 eject(弹出)。

2️⃣ craco.config.js 从哪里来的?

它是 开发者手动创建 的,默认 CRA 项目没有,需要安装 CRACO 后才使用。

如果你看到 craco.config.js,说明这个 React 项目使用了 CRACO 来覆盖默认配置。

3、如何安装 & 创建 craco.config.js?

✅ 1. 安装 CRACO

bash 复制代码
npm install @craco/craco --save-dev

或者

bash 复制代码
yarn add @craco/craco --dev

✅ 2. 在 React 项目根目录创建 craco.config.js

bash 复制代码
touch craco.config.js

✅ 3. 修改 package.json,替换 react-scripts 为 craco

bash 复制代码
{
  "scripts": {
    "start": "craco start",
    "build": "craco build",
    "test": "craco test"
  }
}

4、项目事例

bash 复制代码
const path = require('path');
const CracoLessPlugin = require('craco-less');
const fs = require('fs');

const rewireBabelLoader = require('craco-babel-loader');
const appDirectory = fs.realpathSync(process.cwd());
const resolveApp = (relativePath) => path.resolve(appDirectory, relativePath);

module.exports = {
  webpack: {
    alias: {
      '@': path.resolve(__dirname, 'src'),
    },
    configure: (webpackConfig, { env }) => {
       if (env === 'production') {
         webpackConfig.output.publicPath = 'https://cdn.unionlao.com/la_unionlao_ios/';
       }
      if (env === 'development' || env === 'test') {
        webpackConfig.devtool = 'eval-source-map';
        webpackConfig.output.publicPath = 'https://cdn.unionlao.com/la_unionlao_ios/';
      }
      if (env !== 'development') {

        webpackConfig.optimization.splitChunks = {
          cacheGroups: {
            commons: {
              chunks: 'all',
              name: 'commons',
              minSize: 0, // 公用模塊的大小限制 bytes
              minChunks: 2, // 公用模塊最少復用次數
              maxInitialRequests: 2,
              priority: 10,
              reuseExistingChunk: true,
            },
          },
        };
      }
      return webpackConfig;
    },
  },
  plugins: [
    {
      plugin: CracoLessPlugin,
    },
    {
      plugin: rewireBabelLoader,
      options: {
        includes: [resolveApp('../../libs')], //put things you want to include in array here
        excludes: [/(node_modules|bower_components)/], //things you want to exclude here
     
      },
    },
  ],
  style: {
    postcss: {
      mode: 'extends',
      loaderOptions: {
        postcssOptions: {
          ident: 'postcss',
          plugins: [
            [
              'postcss-pxtorem',
              {
                rootValue: 37.5,
                unitPrecision: 2,
                // propList: ['*', '!font-size', '!*font-size*'],
                propList: ['*'],
                selectorBlackList: [],
                replace: true,
                mediaQuery: false,
                minPixelValue: 0,
                // exclude: /node_modules/i
              },
            ],
          ],
        },
      },
    },
  },
};
相关推荐
小小书童安东尼几秒前
node实现自动生成vue页面,更新router
node.js
顾洋洋1 分钟前
WASM与OPFS组合技系列三(魔改写操作)
前端·javascript·webassembly
清粥油条可乐炸鸡8 分钟前
el-transfer穿梭框数据量过大的解决方案
前端·javascript
天天扭码8 分钟前
Trae 04.22 版本:前端学习者的智能成长助手
前端·trae
snakeshe101011 分钟前
深入解析React Hooks:useCallback与useMemo的原理与区别
前端
听风吹等浪起12 分钟前
html5:从零构建经典游戏-扫雷游戏
前端·html·html5
独立开阀者_FwtCoder13 分钟前
TypeScript 是怎么工作的?一文带你深入编译器内部流程
前端·javascript·面试
独立开阀者_FwtCoder18 分钟前
前端自适应方案全面解析:打造多端适配的现代网页
前端·javascript·面试
万事胜意50728 分钟前
前端切换Tab数据缓存实践
前端
渣渣宇a28 分钟前
Three_3D_Map 中国多个省份的组合边界绘制,填充背景
前端·javascript·three.js