使用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
              },
            ],
          ],
        },
      },
    },
  },
};
相关推荐
Aliex_git1 小时前
跨域请求笔记
前端·网络·笔记·学习
37方寸1 小时前
前端基础知识(Node.js)
前端·node.js
powerfulhell1 小时前
寒假python作业5
java·前端·python
木子啊2 小时前
前端组件化:模板继承拯救发际线
前端
三十_A2 小时前
零基础通过 Vue 3 实现前端视频录制 —— 从原理到实战
前端·vue.js·音视频
前端小菜袅2 小时前
PC端原样显示移动端页面方案
开发语言·前端·javascript·postcss·px-to-viewport·移动端适配pc端
We་ct2 小时前
LeetCode 228. 汇总区间:解题思路+代码详解
前端·算法·leetcode·typescript
爱问问题的小李2 小时前
ue 动态 Key 导致组件无限重置与 API 重复提交
前端·javascript·vue.js
子兮曰2 小时前
深入Vue 3响应式系统:为什么嵌套对象修改后界面不更新?
前端·javascript·vue.js
CHU7290352 小时前
直播商城APP前端功能全景解析:打造沉浸式互动购物新体验
java·前端·小程序