ShuiRuTian / time-analytics-webpack-plugin

Analytics the time cost of loaders and plugins in webpack, to optimise accordingly.
31 stars 0 forks source link

[BUG] Invalid API schema in conjunction with craco-esbuild #7

Open poshiemaaat opened 1 year ago

poshiemaaat commented 1 year ago

Describe the bug Using both this package in addition to craco-esbuild to build yields an invalid schema that gets passed to webpack.

To Reproduce Yes - pasted a working craco.config.ts to reproduce the issue.

Expected behavior I'd expect the time analytics rules to not clobber the esbuild rules, but I'm not entirely sure if that's correct?

Screenshots package.json

{
 "devDependencies": {
    "@craco/craco": "^7.1.0",
    "@craco/types": "^7.1.0",
    "time-analytics-webpack-plugin": "^0.1.20",
    "craco-esbuild": "^0.5.2",
}

craco.config.ts

import type { CracoConfig, CracoWebpackConfig } from "@craco/types";
import { TimeAnalyticsPlugin } from 'time-analytics-webpack-plugin';

const CracoEsbuildPlugin = require('craco-esbuild');

const config = {
    eslint: {
        enable: false,
    },
    plugins: [
        {
            plugin: CracoEsbuildPlugin,
        },
    ],
    webpack: {
        configure: (webpackConfig) => {

            const foo = TimeAnalyticsPlugin.wrap({
                devtool: "source-map",
                ignoreWarnings: [/Failed to parse source map.*wry/],
                ...webpackConfig,
            });

            // this will console log below
            console.log((webpackConfig.module as any).rules[1])
            console.log("result", (foo.module as any).rules[1])

            return foo;
        }
    } as CracoWebpackConfig,
} satisfies CracoConfig;

export default config;
> craco build
# first console log
{
  oneOf: [
    {
      test: [Array],
      type: 'asset',
      mimetype: 'image/avif',
      parser: [Object]
    },
    { test: [Array], type: 'asset', parser: [Object] },
    { test: /\.svg$/, use: [Array], issuer: [Object] },
    {
      test: /\.(js|mjs|jsx|ts|tsx)$/,
      include: '/Users/project/src',
      use: [Array]
    },
    {
      test: /\.(js|mjs)$/,
      exclude: /@babel(?:\/|\\{1,2})runtime/,
      use: [Array]
    },
    {
      test: /\.css$/,
      exclude: /\.module\.css$/,
      use: [Array],
      sideEffects: true
    },
    { test: /\.module\.css$/, use: [Array] },
    {
      test: /\.(scss|sass)$/,
      exclude: /\.module\.(scss|sass)$/,
      use: [Array],
      sideEffects: true
    },
    { test: /\.module\.(scss|sass)$/, use: [Array] },
    { exclude: [Array], type: 'asset/resource' }
  ]
}
# second console log
result {
  oneOf: [
    {
      test: [Array],
      type: 'asset',
      mimetype: 'image/avif',
      parser: [Object]
    },
    { test: [Array], type: 'asset', parser: [Object] },
    { test: /\.svg$/, use: [Array], issuer: [Object] },
    {
      test: /\.(js|mjs|jsx|ts|tsx)$/,
      include: '/Users/project/src',
      use: [Array]
    },
    {
      test: /\.(js|mjs)$/,
      exclude: /@babel(?:\/|\\{1,2})runtime/,
      use: [Array]
    },
    {
      test: /\.css$/,
      exclude: /\.module\.css$/,
      use: [Array],
      sideEffects: true
    },
    { test: /\.module\.css$/, use: [Array] },
    {
      test: /\.(scss|sass)$/,
      exclude: /\.module\.(scss|sass)$/,
      use: [Array],
      sideEffects: true
    },
    { test: /\.module\.(scss|sass)$/, use: [Array] },
    { exclude: [Array], type: 'asset/resource' }
  ]
}
Creating an optimized production build...
Failed to compile.

Invalid configuration object. Webpack has been initialized using a configuration object that does not match the API schema.
 - configuration.module.rules[1] should be one of these:
   ["..." | object { assert?, compiler?, dependency?, descriptionData?, enforce?, exclude?, generator?, include?, issuer?, issuerLayer?, layer?, loader?, mimetype?, oneOf?, options?, parser?, realResource?, resolve?, resource?, resourceFragment?, resourceQuery?, rules?, scheme?, sideEffects?, test?, type?, use? }, ...]
   -> A rule.
   Details:
    * configuration.module.rules[1].oneOf[3].use[1] has an unknown property 'test'. These properties are valid:
      object { ident?, loader?, options? }
    * configuration.module.rules[1].oneOf[3].use[1] has an unknown property 'include'. These properties are valid:
      object { ident?, loader?, options? }

Additional context I am sad

ShuiRuTian commented 1 year ago

I would argue it's not this plugin's fault.

This plugin will change the config file.

Before the change, configuration.module.rules[1].oneOf[3] is like

    {
      "test": {},
      "include": "D:\\MyRepo\\webpack-analyze-plugin\\packages\\test-craco-1\\src",
      "loader": "D:\\MyRepo\\webpack-analyze-plugin\\node_modules\\.pnpm\\babel-loader@8.3.0_@babel+core@7.21.8_webpack@5.82.0\\node_modules\\babel-loader\\lib\\index.js",
      "options": {
        "customize": "D:\\MyRepo\\webpack-analyze-plugin\\node_modules\\.pnpm\\babel-preset-react-app@10.0.1\\node_modules\\babel-preset-react-app\\webpack-overrides.js",
        "presets": [
          [
            "D:\\MyRepo\\webpack-analyze-plugin\\node_modules\\.pnpm\\babel-preset-react-app@10.0.1\\node_modules\\babel-preset-react-app\\index.js",
            {
              "runtime": "automatic"
            }
          ]
        ],
        "babelrc": false,
        "configFile": false,
        "cacheIdentifier": "development:babel-plugin-named-asset-import@0.3.8:babel-preset-react-app@10.0.1:react-dev-utils@12.0.1:react-scripts@5.0.1",
        "plugins": [
          "D:\\MyRepo\\webpack-analyze-plugin\\node_modules\\.pnpm\\react-refresh@0.11.0\\node_modules\\react-refresh\\babel.js"
        ],
        "cacheDirectory": true,
        "cacheCompression": false,
        "compact": false
      }
    },

After the change of this plugin it's

    {
      "test": {},
      "include": "D:\\MyRepo\\webpack-analyze-plugin\\packages\\test-craco-1\\src",
      "use": [
        "D:\\MyRepo\\webpack-analyze-plugin\\packages\\time-analytics-webpack-plugin\\dist\\loader.js",
        {
          "loader": "D:\\MyRepo\\webpack-analyze-plugin\\node_modules\\.pnpm\\babel-loader@8.3.0_@babel+core@7.21.8_webpack@5.82.0\\node_modules\\babel-loader\\lib\\index.js",
          "options": {
            "customize": "D:\\MyRepo\\webpack-analyze-plugin\\node_modules\\.pnpm\\babel-preset-react-app@10.0.1\\node_modules\\babel-preset-react-app\\webpack-overrides.js",
            "presets": [
              [
                "D:\\MyRepo\\webpack-analyze-plugin\\node_modules\\.pnpm\\babel-preset-react-app@10.0.1\\node_modules\\babel-preset-react-app\\index.js",
                {
                  "runtime": "automatic"
                }
              ]
            ],
            "babelrc": false,
            "configFile": false,
            "cacheIdentifier": "development:babel-plugin-named-asset-import@0.3.8:babel-preset-react-app@10.0.1:react-dev-utils@12.0.1:react-scripts@5.0.1",
            "plugins": [
              "D:\\MyRepo\\webpack-analyze-plugin\\node_modules\\.pnpm\\react-refresh@0.11.0\\node_modules\\react-refresh\\babel.js"
            ],
            "cacheDirectory": true,
            "cacheCompression": false,
            "compact": false
          }
        }
      ]
    },

It's a valid config, however, when it's finally consumed by webpack, it becomes:

        {
            "test": {},
            "include": "D:\\MyRepo\\webpack-analyze-plugin\\packages\\test-craco-1\\src",
            "use": [
                "D:\\MyRepo\\webpack-analyze-plugin\\packages\\time-analytics-webpack-plugin\\dist\\loader.js",
                {
                    "test": {},
                    "include": [
                        "D:\\MyRepo\\webpack-analyze-plugin\\packages\\test-craco-1\\src"
                    ],
                    "loader": "D:\\MyRepo\\webpack-analyze-plugin\\node_modules\\.pnpm\\esbuild-loader@2.21.0_webpack@5.82.0\\node_modules\\esbuild-loader\\dist\\index.js",
                    "options": {
                        "loader": "jsx",
                        "target": "es2015"
                    }
                }
            ]
        },

It's more like the issue of "craco-esbuild", in my personal view.

ShuiRuTian commented 1 year ago

And I would suggest not use create-react-app if you are starting a new project.