wuzekang / antd-theme

Provide runtime dynamic theme for ant design.
https://wuzekang.github.io/antd-theme
55 stars 14 forks source link

Maximum call stack size exceeded compiling antd's base.less #2

Open atractom opened 4 years ago

atractom commented 4 years ago

Using 0.3.3 (thanks!), when

        {
            loader: AntdThemePlugin.loader,
        },

is added to webpack config for less files (see below),

./node_modules/antd/dist/antd.less

Module build failed (from ./node_modules/less-loader/dist/cjs.js):
.clearfix {
    .clearfix();
^
Maximum call stack size exceeded

.

At the very bottom of
node_modules/antd/lib/style/core/base.less there is

// Utility classes
.clearfix {
  .clearfix();
}

(just like under the antd-theme node_modules, which does build/run perfectly well).

Any ideas? Is some less plugin from antd-theme affecting how less treats recursion?

Here's the relevant part of webpack config (as per README.md):

 module: {

    rules: [
      {
        test: /\.less$/,
        use: [
          {
            loader: AntdThemePlugin.loader,
          },
          {
            loader: 'css-loader',
          },
          {
            loader: 'less-loader',
            options: {
              lessOptions: {
                javascriptEnabled: true,
              },
            },
          },
        ]
      }, ...
    ]
  },
atractom commented 4 years ago

... versions of involved packages have been copied from antd-theme package.json as

      "antd": "^4.2.0",
      "antd-theme":  "0.3.3",
      "@ant-design/icons": "^4.1.0",
      "less": "^3.11.1",
      "less-loader": "^6.1.0",
      "react-color": "^2.18.0",
      "clean-webpack-plugin": "^3.0.0",
wuzekang commented 4 years ago

Please use babel-plugin-import to load the less style of each component as needed, fully import dist/index.less is temporarily untested

module: {
  rules: [
    {
      test: /\.(j|t)sx?$/,
      use: [
        {
          loader: 'babel-loader',
          options: {
            plugins: [
              // babel-import-plugin
              ['import', {
                libraryName: 'antd',
                style: true,
              }],
            ],
            presets: [['react-app', { typescript: true }]],
          },
        },
      ],
    },
  ]
}

I will fix this problem later, for the time being you can take this approach

atractom commented 4 years ago

Thank you, this is very helpful and good to know! Incrementally adding what compilation says is missing has got as far as

Module build failed (from ./node_modules/babel-loader/lib/index.js):
Error: .inputSourceMap must be a boolean, object, or undefined

.

Trying stuff like

process.env.NODE_ENV = "production" // attempting to bypass source map issue
...
         {
            loader: 'babel-loader',
            options: {
              sourceMaps: false,
              inputSourceMap: false,

              plugins: [
                // babel-import-plugin [sic]
                ['import', {
                  libraryName: 'antd',
                  style: true,
                }],
              ],
              presets: [['react-app', { typescript: true }]],
            },

and plenty of googling has not fixed it yet. Any ideas? I will also update here for readers if a solution is found.

wuzekang commented 4 years ago

Will it be the version of babel? My package.json is like this, can be used normally

{
  "name": "antd-theme-app",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "start": "cross-env NODE_ENV=development webpack-dev-server --config ./webpack.config.js --open"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "antd": "^4.2.5",
    "antd-theme": "^0.3.3",
    "react": "^16.13.1",
    "react-dom": "^16.13.1"
  },
  "devDependencies": {
    "@babel/core": "^7.10.0",
    "@babel/preset-env": "^7.10.0",
    "babel-loader": "^8.1.0",
    "babel-plugin-import": "^1.13.0",
    "babel-preset-react-app": "^9.1.2",
    "clean-webpack-plugin": "^3.0.0",
    "cross-env": "^7.0.2",
    "css-loader": "^3.5.3",
    "html-webpack-plugin": "^4.3.0",
    "less": "^3.11.1",
    "less-loader": "^6.1.0",
    "webpack": "^4.43.0",
    "webpack-cli": "^3.3.11",
    "webpack-dev-server": "^3.10.3"
  }
}

Please provide a minimal reproduction, let me see what is the reason, thank you~

atractom commented 4 years ago

... thank you. I had tried several combinations of the versions (some of which need more or less (adjective!) packages to be explicitly added), including the ones from the antd-theme package.json, but so far, none of them seem to affect the result (inputSourceMap must be a boolean, object, or undefined). I am not even totally convinced that it is a problem caused by antd-theme - maybe it's just an unfortunate combination of everything we depend on (including tools, and the versions!). I did try to minimise before I created the issue but was not able to recreate the same error, yet, except in the full project, since our stack is deeper than what I have let on so far (we use scalajs and some tools and config from its ecosystem to deal with npm and webpack), to keep the discussion focused and less confusing, so I think it would be more time-consuming for you than we should consider reasonable. In case it helps us resolve this, and fyi, it seems there is a limited number of ways babel can officially be configured, according to their docs,, with .babelerc, or babel.config.json files. and have checked of these provided/used by other packages and none mention source map related settings, so it is not clear what babel-loader is objecting to, and what is overriding our explicit config.
Since, in reality, we would probably not choose to include babel in such an already tall stack anyway, maybe we should just wait until the original issue (stack overflow when dealing with antd.less) is addressed and not get more distracted with this, which is at best, a temporary workaround, in our case. Of course, one likes to resolve this sort of stuff, if just out of curiosity/human nature, but it seems there are plenty of blackholes like this that can keep one entertained full-time in the JS world :) If you have some idea when you might look at the stack overflow issue, or can give some clues or if you already know where/why the stack issue is happening, this might help us make a pragmatic decision and enjoy this using plugin, which looks great, if we could just get it working in our stack.

atractom commented 4 years ago

... perhaps another clue: We have some config called fastopt-loader.js

const fs = require("fs");
const path = require("path");
module.exports = function(source) {
  const sourceMapPath = source.substring(
    source.lastIndexOf("//# sourceMappingURL=") + "//# sourceMappingURL=".length
  ).trim();

  const map = JSON.parse(fs.readFileSync(sourceMapPath, { encoding: "utf-8" }));
  map.sources = map.sources.map(s => {
    if (s.startsWith("http://") || s.startsWith("https://")) {
      return s;
    } else {
      return "file://" + path.resolve(s);
    }
  })

  this.callback(null, source, map);
};

which is used in webpack config as follows

  module: {
    noParse: (content) => {
      return content.endsWith("-fastopt.js");
    },
    rules: [
      {
        test: /\-fastopt.js$/,
        use: [ require.resolve('./fastopt-loader.js') ]
      }
    ]
  }

If we change the final argument to this.callback from map to false, then we get back to errors like

Maximum call stack size exceeded
[error]       Error in undefined (line undefined, column undefined)
[error]     at render.then.catch.lessError (.../node_modules/less-loader/dist/index.js:50:14)

So, we may have 2 problems 1 - babel doesn't like the scalajs sourcemap (or it may be just too big for it, possibly around 10MB in dev mode for this project with many dependencies all packed into 1 js file) and 2 - the problems less is having, maybe due to plugins, with stack overflow (possibly down to the clearfix recursion in antd.less.

atractom commented 4 years ago

I notice you marked it as a bug in antd-theme. But is "Note: This way will load the styles of all components, regardless of your demand, which cause style option of babel-plugin-import not working." relevant?

We should not put more time into trying to get babel working unless somebody already knows how to make the loader respect inputSourceMap: false (or how to override whatever is overriding this!) and anything else required to make it "just work". Are you able to give some idea what it might involve to fix the stack-overflow, in case there is somebody into JS/TS to help make a PR, or is it something you'd prefer to address personally?