arackaf / customize-cra

Override webpack configurations for create-react-app 2.0
MIT License
2.78k stars 268 forks source link

addPostcssPlugins doesn't work when react-scripts's version higher than or equal to 5.0.0 #327

Open darkfiredarkhalo opened 2 years ago

darkfiredarkhalo commented 2 years ago

I tested several versions of react-scripts and found that addPostcssPlugins doesn't work when react-scripts's version higher than or equal to 5.0.0
config-overrides.js:

const {
  override,
  addWebpackAlias,
  addPostcssPlugins,
  addLessLoader,
} = require("customize-cra");
const TerserPlugin = require("terser-webpack-plugin");
const path = require("path");
const px2rem = require("postcss-pxtorem");
const autoprefixer = require("autoprefixer");

const addCustomize = () => (config) => {
  if (process.env.NODE_ENV === "production") {
    config.devtool = false;
    if (config.plugins) {
      config.plugins.push(
        new TerserPlugin({
          terserOptions: {
            compress: {
              drop_console: true,
              drop_debugger: true,
              pure_funcs: ["console.log"],
            },
            format: {
              comments: false,
            },
          },
        })
      );
    }
  }
  return config;
};

const lessConfig = () => (config) => {
  config.module.rules.forEach((item) => {
    if (item.oneOf) {
      item.oneOf.forEach((item) => {
        item.use?.forEach((item) => {
          if (
            item.loader?.includes("postcss-loader") &&
            !item?.options?.postcssOptions
          ) {
            const postcssOptions = item.options;
            item.options = { postcssOptions };
          }
        });
      });
    }
  });
  return config;
};

module.exports = {
  webpack: override(
    addWebpackAlias({
      "@": path.resolve(__dirname, "./src"),
    }),
    addCustomize(),
    addPostcssPlugins([
      autoprefixer(),
      px2rem({
        rootValue: 16,
        unitPrecision: 5,
        propList: ["*"],
        exclude: /node_modules/i,
      }),
    ]),
    addLessLoader(),
    // adjustStyleLoaders(({ use: [, , postcss] }) => {
    //   const postcssOptions = postcss.options;
    //   postcss.options = { postcssOptions };
    // })
    lessConfig()
  ),
};
stephenwong1991 commented 2 years ago

Did you find methods?

darkfiredarkhalo commented 2 years ago

npm run eject

tmf commented 2 years ago

The problem is that the interface of the postcss-loader has changed, and now the CRA webpack.config.js nests the loader options in options.postcssOptions:

https://github.com/facebook/create-react-app/blob/f34d88e30c7d8be7181f728d1abc4fd8d5cd07d3/packages/react-scripts/config/webpack.config.js#L133-L144

while customize-cra's addPostcssPlugins looks for options.ident === 'postcss' instead of options.postcssOptions.ident === 'postcss' in https://github.com/arackaf/customize-cra/blob/7e97127e530cc6827af66061525e29925e347670/src/customizers/webpack.js#L298.

My fix for now, is to make postcss-loader from CRA load the postcss.config.js:


const {
  override,
} = require("customize-cra");

const usePostcssRc = () => (config) => {
  const rules = config.module.rules.find((rule) => Array.isArray(rule.oneOf)).oneOf;
  rules.forEach(
    (r) =>
      r.use &&
      r.use.forEach((u) => {
        if (u.options && u.options.postcssOptions && u.options.postcssOptions.ident === 'postcss') {
          delete u.options.postcssOptions.plugins;
          delete u.options.postcssOptions.config; // this makes the loader load the default config file
        }
      })
  );
  return config;
};

module.exports = {
  webpack: override(
    usePostcssRc(),
  ),
};
leon2018-g commented 1 year ago

The problem is that the interface of the postcss-loader has changed, and now the CRA webpack.config.js nests the loader options in options.postcssOptions:

https://github.com/facebook/create-react-app/blob/f34d88e30c7d8be7181f728d1abc4fd8d5cd07d3/packages/react-scripts/config/webpack.config.js#L133-L144

while customize-cra's addPostcssPlugins looks for options.ident === 'postcss' instead of options.postcssOptions.ident === 'postcss' in

https://github.com/arackaf/customize-cra/blob/7e97127e530cc6827af66061525e29925e347670/src/customizers/webpack.js#L298

. My fix for now, is to make postcss-loader from CRA load the postcss.config.js:


const {
  override,
} = require("customize-cra");

const usePostcssRc = () => (config) => {
  const rules = config.module.rules.find((rule) => Array.isArray(rule.oneOf)).oneOf;
  rules.forEach(
    (r) =>
      r.use &&
      r.use.forEach((u) => {
        if (u.options && u.options.postcssOptions && u.options.postcssOptions.ident === 'postcss') {
          delete u.options.postcssOptions.plugins;
          delete u.options.postcssOptions.config; // this makes the loader load the default config file
        }
      })
  );
  return config;
};

module.exports = {
  webpack: override(
    usePostcssRc(),
  ),
};

hi, how to load from postcss.config.js, I do like this, but still not work


 addPostcssPlugins([
    require('@jonny1994/postcss-px-to-viewport')({
      unitToConvert: 'px', 
      viewportWidth: 1920,
      viewportUnit: 'rem',
    })
  ]),
  usePostcssRc(),
gMorning-Wp commented 1 year ago

addPostcssPlugins

The problem is that the interface of the postcss-loader has changed, and now the CRA webpack.config.js nests the loader options in options.postcssOptions: https://github.com/facebook/create-react-app/blob/f34d88e30c7d8be7181f728d1abc4fd8d5cd07d3/packages/react-scripts/config/webpack.config.js#L133-L144 while customize-cra's addPostcssPlugins looks for options.ident === 'postcss' instead of options.postcssOptions.ident === 'postcss' in https://github.com/arackaf/customize-cra/blob/7e97127e530cc6827af66061525e29925e347670/src/customizers/webpack.js#L298

. My fix for now, is to make postcss-loader from CRA load the postcss.config.js:


const {
  override,
} = require("customize-cra");

const usePostcssRc = () => (config) => {
  const rules = config.module.rules.find((rule) => Array.isArray(rule.oneOf)).oneOf;
  rules.forEach(
    (r) =>
      r.use &&
      r.use.forEach((u) => {
        if (u.options && u.options.postcssOptions && u.options.postcssOptions.ident === 'postcss') {
          delete u.options.postcssOptions.plugins;
          delete u.options.postcssOptions.config; // this makes the loader load the default config file
        }
      })
  );
  return config;
};

module.exports = {
  webpack: override(
    usePostcssRc(),
  ),
};

hi, how to load from postcss.config.js, I do like this, but still not work

 addPostcssPlugins([
    require('@jonny1994/postcss-px-to-viewport')({
      unitToConvert: 'px', 
      viewportWidth: 1920,
      viewportUnit: 'rem',
    })
  ]),
  usePostcssRc(),

He wants you to use postcss.config.js not addPostcssPlugins, and I tried it to work