craco.config.js 在react 中配置webpack

4,546 阅读2分钟

craco.config.js 在react 中配置webpack

创建项目

npx create-react-app <项目名称>

安装依赖

1 修改wepback的配置

npm install @craco/craco --save-dev

2 支持less

npm install craco-less --save-dev

3 支持装饰器

npm install @babel/plugin-proposal-decorators --save-dev

4 配置按需加载

npm babel-plugin-import --save-dev


修改package.json sciprt 脚本命令

/* package.json */
"scripts": {
-   "start": "react-scripts start",
-   "build": "react-scripts build",
-   "test": "react-scripts test",
+   "start": "craco start",
+   "build": "craco build",
+   "test": "craco test",
}

项目根目录新建craco.config.js 配置文件

别名配置

const path = require("path")
const addPath = dir => path.join(__dirname,dir);
module.exports = {
    webpack:{
        alias:{
            "@":addPath("src")
        }
    },
}

第三方ui库按需加载,如antd

const cracoLess = require("craco-less");//单独配置babel无效,需要和craco-less 一起样式才有效果
module.exports = {
    babel:{
        plugins:[
            //第一个 style 为 true ,需要配置 craco-less一起才能生效
           ["import",{ libraryName: 'antd', style: true }];
            //第二种 style 为css ,不需要 craco-less
            // ['import', { libraryName: 'antd', libraryDirectory: 'es', style: "css" }],

        ]
    },
    plugins:[
        {
            plugin: cracoLess,
            options: {
              lessLoaderOptions: {
                lessOptions: {
                  modifyVars: { '@primary-color': '#1890ff' },
                  javascriptEnabled: true,
                   //配置全局less 变量,不需要在使用的地方导入了
                   globalVars: {
                    hack: `true; @import '~@/assets/style/variable.less';`
                  }
                },
              },
            },
          },

    ],
}

配置cdn外部资源不打包

const path = require("path")
const addPath = dir => path.join(__dirname,dir);
module.exports = {
    webpack:{
        externals:{
            echarts: "echarts",
        }
    },
}

配置接口跨域代理

const path = require("path")
const addPath = dir => path.join(__dirname,dir);
module.exports = {
   devServer:{
        proxy: {
            "/api": {
                target: 'http://localhost:3001',
                changeOrigin: true,
                pathRewrite: {
                    "^/api": "/api"
                }
            },
        } 
    }
}

分割第三方库打包,自定义webpack 配置

module.exports = {
    webpack:{
        // ...
        configure: (webpackConfig, { env, paths }) =>{
            webpackConfig.devtool = false;
            webpackConfig.optimization= {
                splitChunks: {
                    chunks: 'async',
                    minSize:  40000,
                    maxAsyncRequests: 5, // 最大异步请求数
                    maxInitialRequests: 4, // 页面初始化最大异步请求数
                    automaticNameDelimiter: '~', // 解决命名冲突
                    // name: true值将会自动根据切割之前的代码块和缓存组键值(key)自动分配命名,否则就需要传入一个String或者function.
                    name: true,
                    cacheGroups: {
                    common: {
                        name: 'chunk-common',
                        chunks: 'all',
                        test: /[\/]node_modules[\/](react|react-dom|react-router|redux-saga|dva|react-router-dom|draft-js/lib|core-js|@antv/data-set/build|)[\/]/,
                        priority: -10,
                        },
                        antd: {
                        name: 'chunk-antd',
                        chunks: 'all',
                        test: /[\/]node_modules[\/](@ant-design|antd|moment|immutable/dist|rc-calendar/es|braft-finder/dist|lodash|rc-tree/es)[\/]/,
                        priority: -11,
                        },
                        echarts: {
                        name: 'chunk-echarts',
                        chunks: 'all',
                        test: /[\/]node_modules[\/](echarts)[\/]/,
                        priority: 10,
                        },

                    }
                }
            }
            }
        console.log(webpackConfig)
        console.log("环境:",env,paths)
        return webpackConfig

    }
}

打包依赖插件分析webpack-bundle-analyzer

const webpackBundleAnalyzer = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
const isPro = (dev)=>dev==="production";
module.exports = {
   webpack:{

        configure: (webpackConfig, { env, paths }) =>{
             if(isPro(env)){
                webpackConfig.plugins.push(new webpackBundleAnalyzer());
             }
        }
    }       
}

moment时间插件库过大,打包指定语言

const webpack = require("webpack")
module.exports = {
    //...
   webpack:{ 
        configure: (webpackConfig, { env, paths }) =>{
            webpackConfig.plugins.push(new webpack.ContextReplacementPlugin(/moment[/\]locale$/, /zh-cn/));
        }
    }       
}

打包压缩gz,使用库 compression-webpack-plugin(建议^5 的版本,过高会报错)

const compressionWebpackPlugin = require("compression-webpack-plugin")
module.exports = {
   webpack:{ 
        configure: (webpackConfig, { env, paths }) =>{
           webpackConfig.plugins.push(new compressionWebpackPlugin({
                filename: '[path].gz[query]',
                algorithm: 'gzip',
                // test: /.js$|.html$|.json$|.css/,
                test: /.js$|.json$|.css/,
                threshold: 10240, // 只有大小大于该值的资源会被处理
                minRatio: 0.8, // 只有压缩率小于这个值的资源才会被处理
                // deleteOriginalAssets: true // 删除原文件
            }))
        }
    }       
}

配置支持装饰器,安装库 @babel/plugin-proposal-decorators

module.exports = {
    babel:{
        plugins:[
           ['@babel/plugin-proposal-decorators', { legacy: true }]
        ]
    },
}

使用postcss-px2rem-exclude 和lib-flexible 做移动适配

const px2rem = require("postcss-px2rem-exclude");
module.exports = {
    style:{
        postcss:{
            plugins:[
                px2rem({
                    remUnit: 37.5,
                    exclude:/node-modules/i
                })
            ]
        }
    },
}