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.44k stars 498 forks source link

Version upgrade issue of react-script v4-> v5 and craco v6 -> v7 #475

Open asurwt opened 2 years ago

asurwt commented 2 years ago

In existing project we were trying to upgrade react-scripts from V4.0.3 => V5.0.1. After upgrade, Craco also need upgradation, so we have upgraded Craco V6.1.2 => V7.0.0. It creating issue with webpack-modernizr-loader. webpack-dev-server also not working. Below i have mentioned errors which i am facing.

node_modules/@craco/craco/dist/lib/plugin-utils.js:26
    throw new Error("".concat(message, "\n\n") +
          ^

Error: failed to add webpack-modernizr-loader

This error probably occurred because you updated react-scripts or craco. Please try updating craco to the latest version:

   $ yarn upgrade craco

Or:

   $ npm update craco

If that doesn't work, craco needs to be fixed to support the latest version.
Please check to see if there's already an issue in the gsoft-inc/craco repo:

   * https://github.com/gsoft-inc/craco/issues?q=is%3Aissue+webpack

If not, please open an issue and we'll take a look. (Or you can send a PR!)

You might also want to look for related issues in the craco and create-react-app repos:

   * https://github.com/dilanx/craco/issues?q=is%3Aissue+webpack
   * https://github.com/facebook/create-react-app/issues?q=is%3Aissue+webpack

    at throwUnexpectedConfigError (/node_modules/@craco/craco/dist/lib/plugin-utils.js:26:11)
    at throwError (/client/craco.config.js:6:5)
    at configure (/client/craco.config.js:52:40)
    at giveTotalControl (/node_modules/@craco/craco/dist/lib/features/webpack/merge-webpack-config.js:76:25)
    at mergeWebpackConfig (/node_modules/@craco/craco/dist/lib/features/webpack/merge-webpack-config.js:116:38)
    at overrideWebpackDev (/node_modules/@craco/craco/dist/lib/features/webpack/override.js:8:80)
    at //node_modules/@craco/craco/dist/scripts/start.js:21:39
npm ERR! Lifecycle script `start-local` failed with error: 
npm ERR! Error: command failed 
npm ERR!   in workspace: client@1.0.0 
npm ERR!   at location: /client 

image

CRACO config

const path = require('path');
const { addBeforeLoader, loaderByName, throwUnexpectedConfigError } = require('@craco/craco');
const BundleAnalyzerPlugin = require("webpack-bundle-analyzer").BundleAnalyzerPlugin;

const throwError = (message) =>
  throwUnexpectedConfigError({
      packageName: 'craco',
      githubRepo: 'gsoft-inc/craco',
      message,
      githubIssueQuery: 'webpack',
  });

  module.exports = () => {
    const plugins = [];

    // if (process.env.NODE_ENV !== "production") {
    //   plugins.push(new BundleAnalyzerPlugin())
    // }

    return {
      eslint: {
        enable: true,
      },
      style: {
        css: {
          loaderOptions: {
            modules: { localIdentName: '[local]_[hash:base64:5]' },
          },
        },
      },
      webpack: {
        alias: {
          react: path.resolve(__dirname, '../node_modules', 'react'),
          'react-dom': path.resolve(__dirname, '../node_modules', 'react-dom'),
          'modernizr': path.resolve(__dirname, "./.modernizrrc.js")
        },
        plugins,
        configure: webpackConfig => {
          // Adding modernizr loader Start
          const modernizrLoader = {
            loader: "webpack-modernizr-loader",
            test: /\.modernizrrc\.js$/,
          };

          const { isAdded: modernizrLoaderIsAdded } = addBeforeLoader(webpackConfig, loaderByName('url-loader'), modernizrLoader);
          if (!modernizrLoaderIsAdded) throwError('failed to add webpack-modernizr-loader');
          // Adding modernizr loader End

          const scopePluginIndex = webpackConfig.resolve.plugins.findIndex(
            ({ constructor }) => constructor && constructor.name === 'ModuleScopePlugin'
          );

          const [ clientSrc ] = webpackConfig.resolve.plugins[scopePluginIndex].appSrcs;
          const psvServices = path.resolve(clientSrc,'../..');

          webpackConfig.resolve.plugins[scopePluginIndex].appSrcs.push(psvServices);

          return webpackConfig;
        }
      }
    }
  };

package.json

"dependencies": {
    "@babel/polyfill": "^7.0.0",
    "@babel/runtime-corejs2": "^7.4.3",
    "@instana/collector": "^1.129.0",
    "@material-ui/core": "^4.11.4",
    "@material-ui/icons": "^4.9.1",
    "@material-ui/lab": "^4.0.0-alpha.49",
    "algoliasearch": "^3.29.0",
    "apollo-errors": "^1.9.0",
    "apollo-server-koa": "^1.3.4",
    "aws-sdk": "^2.281.1",
    "base-64": "^0.1.0",
    "basic-auth": "^2.0.0",
    "blocked": "^1.3.0",
    "bunyan": "^1.8.12",
    "cheerio": "^1.0.0-rc.2",
    "classnames": "^2.2.6",
    "cls-hooked": "^4.2.2",
    "consul": "^0.34.0",
    "cross-env": "^5.2.0",
    "crypto-js": "^3.1.9-1",
    "csvtojson": "^1.1.9",
    "date-fns": "^2.11.1",
    "debug": "^3.1.0",
    "dotenv": "^8.2.0",
    "draft-js": "0.10.4",
    "draft-js-export-html": "^1.3.3",
    "draft-js-plugins-editor": "^2.1.1",
    "ejs": "^3.1.8",
    "element-scroll-polyfill": "^1.0.1",
    "eslint-plugin-react-hooks": "^4.2.0",
    "fetch-timeout": "^0.0.2",
    "flexboxgrid": "^6.3.1",
    "form-data": "^2.3.2",
    "graphql": "^0.13.2",
    "graphql-tools": "^3.0.5",
    "hare-niemeyer": "^2.0.0",
    "history": "^4.7.2",
    "humps": "^2.0.1",
    "jest-canvas-mock": "^2.2.0",
    "joi": "^17.6.4",
    "jsonwebtoken": "^8.3.0",
    "koa": "^2.5.2",
    "koa-body": "^4.0.4",
    "koa-bunyan-logger": "^2.1.0",
    "koa-compress": "^3.0.0",
    "koa-convert": "^1.2.0",
    "koa-cookie": "^1.0.0",
    "koa-cors": "0.0.16",
    "koa-json": "^2.0.2",
    "koa-router": "^7.4.0",
    "koa-validate": "^1.0.7",
    "lodash": "^4.17.21",
    "memoize-one": "^5.1.1",
    "merge-graphql-schemas": "^1.5.1",
    "modernizr": "^3.12.0",
    "moment": "^2.29.4",
    "moment-timezone": "^0.5.21",
    "mutation-observer": "^1.0.3",
    "node-fetch": "^2.6.7",
    "normalize.css": "^8.0.0",
    "npm-link-shared": "^0.5.6",
    "oauth-1.0a": "^2.2.4",
    "object-hash": "^1.3.1",
    "openapi-request-validator": "^10.0.0",
    "openapi-response-validator": "^10.0.0",
    "openapi-schema-validator": "^10.0.0",
    "parse-domain": "^2.1.6",
    "pg": "^8.6.0",
    "pg-format": "^1.0.4",
    "pg-pool": "^3.2.2",
    "prop-types": "^15.6.2",
    "puresql": "^1.8.0",
    "query-string": "5",
    "raf": "^3.4.1",
    "react": "^17.0.2",
    "react-aria-live": "^2.0.5",
    "react-card-flip": "^1.0.11",
    "react-copy-to-clipboard": "^5.0.1",
    "react-day-picker": "^7.1.10",
    "react-dom": "^17.0.2",
    "react-dotdotdot": "^1.2.3",
    "react-dropzone": "^4.2.13",
    "react-grid-layout": "^0.18.3",
    "react-html-parser": "^2.0.2",
    "react-lazyload": "^2.6.2",
    "react-media": "^1.8.0",
    "react-modal": "^3.5.1",
    "react-paginate": "^6.2.1",
    "react-popper": "^1.3.3",
    "react-redux": "^7.2.6",
    "react-router-dom": "5.3.0",
    "react-scroll": "^1.7.10",
    "react-split-pane": "^0.1.87",
    "react-sticky": "^6.0.3",
    "react-tabs": "^2.2.2",
    "react-timeout": "^1.1.1",
    "react-tooltip": "^3.11.1",
    "react-transition-group": "^4.4.1",
    "react-truncate": "^2.4.0",
    "react-virtualized": "^9.21.0",
    "reactable": "1.0.0",
    "recharts": "^2.1.15",
    "redux": "^4.0.0",
    "redux-devtools-extension": "^2.13.7",
    "redux-localstorage": "^0.4.1",
    "redux-thunk": "^2.3.0",
    "request": "^2.88.0",
    "request-ip": "^2.1.3",
    "reselect": "^4.0.0",
    "resize-observer-polyfill": "^1.5.1",
    "sequelize": "^6.6.5",
    "swagger2-koa": "^1.0.2",
    "text-encoding": "^0.6.4",
    "uglify-js": "^3.13.3",
    "universal-cookie": "^2.2.0",
    "url-pattern": "^1.0.3",
    "use-resize-observer": "^6.1.0-alpha.3",
    "uuid": "^3.3.2",
    "validate.js": "^0.12.0",
    "whatwg-fetch": "^3.4.1",
    "xlsx": "^0.18.5"
  },
  "devDependencies": {
    "@babel/cli": "^7.12.10",
    "@babel/core": "^7.14.6",
    "@babel/node": "^7.14.7",
    "@babel/eslint-parser": "^7.19.1",
    "@babel/plugin-proposal-class-properties": "^7.0.0",
    "@babel/plugin-syntax-dynamic-import": "^7.0.0",
    "@babel/plugin-syntax-import-meta": "^7.0.0",
    "@babel/plugin-transform-regenerator": "^7.0.0",
    "@babel/plugin-transform-runtime": "^7.0.0",
    "@babel/preset-env": "^7.14.7",
    "@babel/preset-react": "^7.0.0",
    "@babel/register": "^7.0.0",
    "@craco/craco": "^7.0.0",
    "@testing-library/jest-dom": "^5.11.4",
    "@testing-library/react": "^11.1.0",
    "@testing-library/react-hooks": "^7.0.0",
    "@testing-library/user-event": "^12.1.10",
    "@welldone-software/why-did-you-render": "^2.4.0",
    "@wojtekmaj/enzyme-adapter-react-17": "^0.6.1",
    "autoprefixer": "^9.0.1",
    "babel-jest": "^28.1.3",
    "babel-loader": "^7.1.1",
    "babel-plugin-dynamic-import-node": "^2.3.3",
    "babel-preset-es2015": "^6.24.1",
    "babel-preset-react": "^6.24.1",
    "babel-register": "^6.26.0",
    "babel-runtime": "^6.23.0",
    "browser-sync": "^2.27.10",
    "command-line-args": "^5.0.2",
    "concurrently": "^6.3.0",
    "connect-history-api-fallback": "^1.5.0",
    "css-loader": "^6.7.1",
    "cypress-failed-log": "^2.1.0",
    "enzyme": "^3.11.0",
    "eslint": "^7.27.0",
    "eslint-config-airbnb": "^18.2.1",
    "eslint-config-prettier": "^8.3.0",
    "eslint-config-react-app": "^6.0.0",
    "eslint-import-resolver-alias": "^1.1.2",
    "eslint-loader": "^1.9.0",
    "eslint-plugin-flowtype": "^5.7.2",
    "eslint-plugin-import": "^2.23.3",
    "eslint-plugin-jsx-a11y": "^6.4.1",
    "eslint-plugin-prettier": "^3.4.0",
    "eslint-plugin-react": "^7.23.2",
    "file-loader": "^1.1.11",
    "highlight.js": "^9.12.0",
    "husky": "^8.0.1",
    "hygen": "^6.2.11",
    "identity-obj-proxy": "^3.0.0",
    "jest-junit": "^1.5.1",
    "json-loader": "^0.5.7",
    "lerna": "^5.4.0",
    "local-ssl-proxy": "^1.3.0",
    "madge": "^5.0.1",
    "markdown-it": "^13.0.0",
    "nodemon": "^2.0.20",
    "path-to-regexp": "^2.2.1",
    "pixrem": "^5.0.0",
    "postcss": "^7.0.14",
    "postcss-apply": "^0.12.0",
    "postcss-calc": "^7.0.1",
    "postcss-custom-properties": "^8.0.10",
    "postcss-custom-selectors": "^5.1.2",
    "postcss-flexbugs-fixes": "^4.1.0",
    "postcss-import": "^12.0.1",
    "postcss-loader": "^3.0.0",
    "postcss-media-minmax": "^4.0.0",
    "postcss-nesting": "^7.0.0",
    "postcss-selector-matches": "^4.0.0",
    "postcss-selector-not": "^4.0.0",
    "prettier": "^2.3.0",
    "react-hot-loader": "^4.3.4",
    "react-router-sitemap": "^1.2.0",
    "react-scripts": "^5.0.1",
    "react-test-renderer": "17.0.2",
    "redux-mock-store": "^1.5.3",
    "regenerator-runtime": "^0.13.2",
    "rimraf": "^2.6.2",
    "should": "^13.2.2",
    "sqlite3": "^5.1.1",
    "style-loader": "^3.3.1",
    "stylelint": "^13.13.1",
    "stylelint-config-standard": "^19.0.0",
    "url-loader": "^4.1.1",
    "wait-for-expect": "^3.0.1",
    "webpack-bundle-analyzer": "^4.4.2"
  },

Additional information (anything else that could be useful for us to help you solve your problem)

dilanx commented 2 years ago

Is that craco config the same one you used with craco 6?

asurwt commented 2 years ago

Is that craco config the same one you used with craco 6?

yes the shared config is of craco 6, but i have made some required changed as per craco 7. Below is the config.

const path = require('path');
const { addBeforeLoader, loaderByName, throwUnexpectedConfigError } = require('@craco/craco');
const BundleAnalyzerPlugin = require("webpack-bundle-analyzer").BundleAnalyzerPlugin;

const throwError = (message) =>
  throwUnexpectedConfigError({
    packageName: 'craco',
    githubRepo: 'gsoft-inc/craco',
    message,
    githubIssueQuery: 'webpack',
});

module.exports = {
  eslint: {
    enable: true,
  },
  style: {
    css: {
      loaderOptions: {
        modules: { 'localIdentName': '[local]_[hash:base64:5]' }
      }
    }
  },
  webpack: {
    alias: {
      react: path.resolve(__dirname, '../node_modules', 'react'),
      'react-dom': path.resolve(__dirname, '../node_modules', 'react-dom'),
      'modernizr': path.resolve(__dirname, "./.modernizrrc.js")
    },
    configure: webpackConfig => {
      webpackConfig.resolve.fallback = {
        fs: false,
        path: require.resolve("path-browserify")
      };

      // Adding modernizr loader Start
      const modernizrLoader = {
        loader: "webpack-modernizr-loader",
        test: /\.modernizrrc\.js$/,
      };
      const { isAdded: modernizrLoaderIsAdded } = addBeforeLoader(webpackConfig, loaderByName('url-loader'), modernizrLoader);
      console.log("modernizrLoaderIsAdded: ", modernizrLoaderIsAdded)
      if (!modernizrLoaderIsAdded) throwError('failed to add webpack-modernizr-loader');
      // Adding modernizr loader End

      const scopePluginIndex = webpackConfig.resolve.plugins.findIndex(
        ({ constructor }) => constructor && constructor.name === 'ModuleScopePlugin'
      );

      const [clientSrc] = webpackConfig.resolve.plugins[scopePluginIndex].appSrcs;
      const psvServices = path.resolve(clientSrc, '../..');

      webpackConfig.resolve.plugins[scopePluginIndex].appSrcs.push(psvServices);

      return webpackConfig;
    }
  }
}
rahulagarwal11 commented 1 year ago

@dilanx @asurwt: did you able to figure out the solution to above issue? We are also trying to upgrade the react-scripts from V4.0.3 => V5.0.1. and then also upgrade craco from V6.0.0 => V7.0.0.

After upgrade I see below error:

Invalid configuration object. Webpack has been initialized using a configuration object that does not match the API schema.
 - configuration.devtool should match pattern "^(inline-|hidden-|eval-)?(nosources-)?(cheap-(module-)?)?source-map$".
   BREAKING CHANGE since webpack 5: The devtool option is more strict.
   Please strictly follow the order of the keywords in the pattern.
 - configuration.optimization has an unknown property 'namedChunks'. These properties are valid:
   object { checkWasmTypes?, chunkIds?, concatenateModules?, emitOnErrors?, flagIncludedChunks?, innerGraph?, mangleExports?, mangleWasmImports?, mergeDuplicateChunks?, minimize?, minimizer?, moduleIds?, noEmitOnErrors?, nodeEnv?, portableRecords?, providedExports?, realContentHash?, removeAvailableModules?, removeEmptyChunks?, runtimeChunk?, sideEffects?, splitChunks?, usedExports? }
   -> Enables/Disables integrated optimizations.
   Did you mean optimization.chunkIds: "named" (BREAKING CHANGE since webpack 5)?
 - configuration.output has an unknown property 'jsonpFunction'. These properties are valid:
   object { assetModuleFilename?, asyncChunks?, auxiliaryComment?, charset?, chunkFilename?, chunkFormat?, chunkLoadTimeout?, chunkLoading?, chunkLoadingGlobal?, clean?, compareBeforeEmit?, crossOriginLoading?, cssChunkFilename?, cssFilename?, devtoolFallbackModuleFilenameTemplate?, devtoolModuleFilenameTemplate?, devtoolNamespace?, enabledChunkLoadingTypes?, enabledLibraryTypes?, enabledWasmLoadingTypes?, environment?, filename?, globalObject?, hashDigest?, hashDigestLength?, hashFunction?, hashSalt?, hotUpdateChunkFilename?, hotUpdateGlobal?, hotUpdateMainFilename?, iife?, importFunctionName?, importMetaName?, library?, libraryExport?, libraryTarget?, module?, path?, pathinfo?, publicPath?, scriptType?, sourceMapFilename?, sourcePrefix?, strictModuleErrorHandling?, strictModuleExceptionHandling?, trustedTypes?, umdNamedDefine?, uniqueName?, wasmLoading?, webassemblyModuleFilename?, workerChunkLoading?, workerWasmLoading? }
   -> Options affecting the output of the compilation. `output` options tell webpack how to write the compiled files to disk.
   Did you mean output.chunkLoadingGlobal (BREAKING CHANGE since webpack 5)?
dilanx commented 1 year ago

Upgrading to craco v7 includes upgrading webpack from v4 to v5, and these issues (at least the one that @rahulagarwal11 sent) involve configuration that was valid in the older version but is no longer valid in the newer one. Follow the webpack migration instructions to ensure that your config is valid for webpack 5.

rahulagarwal11 commented 1 year ago

@dilanx Thank you for your output, I looked into the shared link, still see the same issue, here is my craco.config

const { DefinePlugin } = require('webpack');
const configureMx = require('@soluto-private/mx-webpack-configure-mx');

module.exports = {
  devServer: {
    https: true,
    headers: {
      'Access-Control-Allow-Origin': '*',
      'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, PATCH, OPTIONS',
      'Access-Control-Allow-Headers': 'X-Requested-With, content-type, Authorization',
    },
  },
  webpack: {
    configure: (webpackConfig, argv) => {
      const config = configureMx(webpackConfig, {
        enabled: true,
        env: argv.env,
        paths: argv.paths,
        orgName: 'soluto',
        projectName: 'gallery',
        prefix: '',
        rootDirectoryLevel: 1,
        mxRequire: require,
        mxApp: 'mx-app.tsx',
        additionalExternals: [/^@soluto-private\/mx-.*/, 'react', 'react-dom'],
      });

      return config;
    },
    plugins: [
      new DefinePlugin({
        ROUTE_PREFIX: JSON.stringify(''),
      }),
    ],
  },
  babel: {
    plugins: ['babel-plugin-styled-components'],
  },
};
dilanx commented 1 year ago

@rahulagarwal11 the issue might lie within the @soluto-private/mx-webpack-configure-mx. The package is private so I can't view it myself. Does that package use webpack 5? Your webpack configuration is using properties that are no longer valid, and that might be from that package.