dilanx / craco

Create React App Configuration Override, an easy and comprehensible configuration layer for Create React App.
https://craco.js.org
Apache License 2.0
7.43k stars 499 forks source link

run craco start/build, it will exec twice craco.config.js #518

Closed little-buddy closed 1 year ago

little-buddy commented 1 year ago

What's happening run craco start/build, it will exec twice craco.config.js

What should happen run once

To reproduce craco start or craco build

CRACO version 7.1.0

CRACO config

/* eslint-disable @typescript-eslint/no-var-requires */
const isAnalyze = process.env.ANALYZE;
const path = require('path');
const webpack = require('webpack');
const WebpackBundleAnalyzer =
    require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
const StyleLintPlugin = require('stylelint-webpack-plugin');

const addPath = dir => path.resolve(__dirname, dir);

console.log(new Date().getTime());

module.exports = {
    webpack: {
        // eslint-disable-next-line @typescript-eslint/no-unused-vars
        configure: (webpackConfig, { env, paths }) => {

            webpackConfig.plugins.push(
                new webpack.ContextReplacementPlugin(/moment[/\\]locale$/, /zh-cn/)
            );
            // analyze
            if (isAnalyze) webpackConfig.plugins.push(new WebpackBundleAnalyzer());

            webpackConfig.plugins.push(
                new StyleLintPlugin()

            );

            return webpackConfig;
        },
        babel: {},
        style: {
            postcss: {
                mode: 'file',
            },
        },
        eslint: {
            mode: 'file',
        },
        externals: {

        },
        alias: {
            '@': addPath('./src'),
        },
    },
};

package.json

{
    "name": "cra-t",
    "version": "0.1.0",
    "license": "ISC",
    "scripts": {
        "start": "craco start",
        "build": "craco build",
        "test": "craco test",
        "lint": "eslint --cache .",
        "lint:fix": "eslint --fix .",
        "prettier": "prettier --write .",
        "format": "prettier --check .",
        "analyze": "cross-env ANALYZE=true yarn build"
    },
    "dependencies": {
        "@reduxjs/toolkit": "^1.9.5",
        "@tailwindcss/aspect-ratio": "^0.4.2",
        "@tailwindcss/typography": "^0.5.9",
        "@testing-library/jest-dom": "^5.17.0",
        "@testing-library/react": "^14.0.0",
        "@testing-library/user-event": "^14.4.3",
        "axios": "^1.4.0",
        "moment": "^2.29.4",
        "prettier": "^3.0.0",
        "react": "^18.2.0",
        "react-dom": "^18.2.0",
        "react-redux": "^8.1.2",
        "react-router-dom": "^6.14.2",
        "react-scripts": "^5.0.1",
        "redux-persist": "^6.0.0",
        "redux-thunk": "^2.4.2",
        "sass": "^1.64.2",
        "sass-loader": "^13.3.2",
        "stylelint-webpack-plugin": "^4.1.1",
        "tailwindcss": "^3.3.3",
        "webpack": "^5.88.2",
        "webpack-bundle-analyzer": "^4.9.0"
    },
    "devDependencies": {
        "@babel/plugin-proposal-private-property-in-object": "^7.21.11",
        "@craco/craco": "^7.1.0",
        "@types/jest": "^29.5.3",
        "@types/node": "^20.4.5",
        "@types/react": "^18.2.18",
        "@types/react-dom": "^18.2.7",
        "@types/react-redux": "^7.1.25",
        "@typescript-eslint/eslint-plugin": "^6.2.1",
        "@typescript-eslint/parser": "^6.2.1",
        "autoprefixer": "^10.4.14",
        "cross-env": "^7.0.3",
        "eslint-config-airbnb": "^19.0.4",
        "eslint-config-prettier": "^8.9.0",
        "eslint-plugin-import": "^2.28.0",
        "eslint-plugin-jest": "^27.2.3",
        "eslint-plugin-jsx-a11y": "^6.7.1",
        "eslint-plugin-prettier": "^5.0.0",
        "eslint-plugin-react": "^7.33.1",
        "postcss-nesting": "^12.0.0",
        "postcss-plugin-px2rem": "^0.8.1",
        "stylelint": "^15.10.2",
        "stylelint-config-recess-order": "^4.3.0",
        "stylelint-config-recommended": "^13.0.0",
        "stylelint-config-recommended-scss": "^12.0.0",
        "stylelint-config-standard": "^34.0.0",
        "stylelint-order": "^6.0.3",
        "typescript": "^5.1.6"
    },
    "homepage": ".",
    "browserslist": {
        "production": [
            ">0.2%",
            "not dead",
            "not op_mini all"
        ],
        "development": [
            "last 1 chrome version",
            "last 1 firefox version",
            "last 1 safari version"
        ]
    },
    "husky": {
        "hooks": {
            "pre-commit": "lint-staged"
        }
    },
    "lint-staged": {
        "src/**/*.{js,jsx,ts,tsx,json,css,scss,md}": [
            "prettier --write"
        ]
    }
}

Additional information I found that it executes crac.config.js once to determine if crac.config.js exists, and then again when using merge

dilanx commented 1 year ago

The configuration file isn't guaranteed to be loaded only once. However, the configuration itself should only be loaded once. You can switch your export to be a function instead of an object.

/* craco.config.js */

module.exports = () => {
  // stuff here should only run once

  return {
    // your craco config
  };
};