软件技术学习笔记

个人博客,记录软件技术与程序员的点点滴滴。

Craco辅助函数overrides

这几天,从react-app-rewired切换到CRACO, 发现在重写 webpack 配置函数中也需要相似的 overrides 函数。于是写了一个简单的:

const overrides =
  (...funcArray) =>
  (webpackConfig, { env, paths }) =>
    funcArray.reduce((config, func) => func(config, { env, paths }), webpackConfig);

完整的 craco.config.js 样例:

const deepMerge = require('deepmerge');
const { getPlugin, pluginByName } = require('@craco/craco');
const getClientEnvironment = require('react-scripts/config/env');
const rewireTypingsForCssModule = require('react-app-rewire-typings-for-css-module');
const CracoAlias = require('craco-alias');
// const CracoSassResourcesLoader = require('craco-sass-resources-loader');
// const AddAssetPlugin = require('add-asset-webpack-plugin');

const overrideOptimizationMinimize =
  minimize =>
  (webpackConfig, { env, paths }) => {
    if (minimize !== undefined) {
      webpackConfig.optimization.minimize = minimize;
    }

    return webpackConfig;
  };

const overridePluginOptions =
  (pluginName, options) =>
  (webpackConfig, { env, paths }) => {
    const { isFound, match } = getPlugin(webpackConfig, pluginByName(pluginName));

    if (isFound && match.options !== undefined) {
      match.options = deepMerge(match.options, options);
    }

    return webpackConfig;
  };

const overrideTypingsForCssModule =
  () =>
  (webpackConfig, { env, paths }) =>
    rewireTypingsForCssModule(webpackConfig, env);

const overrides =
  (...funcArray) =>
  (webpackConfig, { env, paths }) =>
    funcArray.reduce((config, func) => func(config, { env, paths }), webpackConfig);

module.exports = {
  style: {
    sass: {
      loaderOptions: {
        // Prefer 'sass' (dart-sass) over 'node-sass' if both packages are installed.
        implementation: require('sass'),
        // Workaround for this bug: https://github.com/webpack-contrib/sass-loader/issues/804
        webpackImporter: false,
      },
    },
  },
  webpack: {
    configure: (webpackConfig, { env, paths }) => {
      return overrides(
        overrideOptimizationMinimize(undefined),
        overridePluginOptions('HtmlWebpackPlugin', {
          templateParameters: getClientEnvironment().raw,
        }),
        overrideTypingsForCssModule(),
      )(webpackConfig, { env, paths });
    },
  },
  plugins: [
    {
      plugin: CracoAlias,
      options: {
        source: 'options',
        baseUrl: './',
        aliases: {
          '@': './src',
        },
      },
    },
  ],
};