Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Filesystem Cache is throwing TypeError: Cannot read property 'length' of undefined from ResolverCachePlugin #11668

Closed
gtwilliams03 opened this issue Oct 13, 2020 · 66 comments · Fixed by #11788

Comments

@gtwilliams03
Copy link

Bug report

What is the current behavior?

Attempting to get the cache working for webpack 5. I have it working on one of my local repos, but this one (a clone of a different website), is throwing an error:

Relevant config:

  cache: {
    type: 'filesystem',
    buildDependencies: {
      config: [ '/Users/xxx/public-web/config/webpack.config.js' ]
    }
  }

Throws this error:

(node:23491) UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'length' of undefined
    at getType (/Users/xxx/public-web/node_modules/enhanced-resolve/lib/util/path.js:41:12)
    at Resolver.isPrivate (/Users/xxx/public-web/node_modules/enhanced-resolve/lib/Resolver.js:446:10)
    at Resolver.parse (/Users/xxx/public-web/node_modules/enhanced-resolve/lib/Resolver.js:430:25)
    at /Users/xxx/public-web/node_modules/enhanced-resolve/lib/ParsePlugin.js:33:29
    at _next0 (eval at create (/Users/xxx/public-web/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:8:1)
    at eval (eval at create (/Users/xxx/public-web/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:30:1)
    at /Users/xxx/public-web/node_modules/webpack/lib/cache/ResolverCachePlugin.js:199:17
    at Hook.eval [as callAsync] (eval at create (/Users/xxx/public-web/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:22:1)
    at Resolver.doResolve (/Users/xxx/public-web/node_modules/enhanced-resolve/lib/Resolver.js:398:16)
    at doRealResolve (/Users/xxx/public-web/node_modules/webpack/lib/cache/ResolverCachePlugin.js:138:13)

Setting the webpack config config: false eliminates the error and the build runs normally.

If the current behavior is a bug, please provide the steps to reproduce.

I see directories being created under my working repo in the node_modules/.cache folder, but not on my problem repo. A .cache folder is created, but no webpack or webpack/client-development folders.

What is the expected behavior?

Cannot figure out why one repo is throwing this error and the other is not.

Other relevant information:
webpack version: 5.0.0
Node.js version: 14.13.1
Operating System: MacOS Catalina 10.15.7
Additional tools:

@alexander-akait
Copy link
Member

hm, maybe you can create reproducible test repo?

@gtwilliams03
Copy link
Author

Right now I am just crawling through the repo that works and the repo that doesn't to try and find any differences. I am baffled - although I am wondering if this is some sort of strange permissions issue since the working repo is quote old (2-3 years) and the problem repo was created in the last month or so.

@gtwilliams03
Copy link
Author

Same computer, same webpack config, different folders.

@alexander-akait
Copy link
Member

@gtwilliams03 Perhaps we are not processing a specific case, perhaps the configuration would be enough to understand it

@gtwilliams03
Copy link
Author

Here is the output of my webpack config:

{
  mode: 'development',
  cache: {
    type: 'filesystem',
    buildDependencies: {
      config: [ '/Users/xxx/public-web/config/webpack.config.js' ]
    }
  },
  optimization: { emitOnErrors: true, concatenateModules: false },
  name: 'client',
  target: 'web',
  devtool: 'source-map',
  resolve: {
    modules: [ '/Users/xxx/public-web/src', 'node_modules' ],
    extensions: [ '.js', '.jsx', '.json' ]
  },
  module: {
    rules: [
      {
        test: /\.(js|jsx)$/,
        exclude: /\/node_modules\/(?!(@restart\/context|@restart\/hooks|autobind-decorator|sort-keys|email-regex|query-string|split-on-first|strict-uri-encode|react-bootstrap-slider)\/).*\//,
        include: [
          '/Users/xxx/public-web/node_modules/@restart/context',
          '/Users/xxx/public-web/node_modules/@restart/hooks',
          '/Users/xxx/public-web/node_modules/autobind-decorator',
          '/Users/xxx/public-web/node_modules/sort-keys',
          '/Users/xxx/public-web/node_modules/email-regex',
          '/Users/xxx/public-web/node_modules/query-string',
          '/Users/xxx/public-web/node_modules/split-on-first',
          '/Users/xxx/public-web/node_modules/strict-uri-encode',
          '/Users/xxx/public-web/node_modules/react-bootstrap-slider',
          '/Users/xxx/public-web/src'
        ],
        use: [
          {
            loader: 'babel-loader',
            options: {
              cacheDirectory: true,
              plugins: [ '@babel/plugin-proposal-class-properties' ],
              presets: [ [ '@babel/preset-env' ], '@babel/preset-react' ]
            }
          }
        ]
      },
      {
        test: /\.scss$/,
        include: /(\/Users\/xxx\/public\-web\/src)/,
        use: [
          { loader: 'style-loader', options: {} },
          {
            loader: 'css-loader',
            options: {
              sourceMap: true,
              modules: { localIdentName: '[name]__[local]___[hash:base64:5]' },
              importLoaders: 1
            }
          },
          { loader: 'postcss-loader', options: { sourceMap: true } },
          {
            loader: 'sass-loader',
            options: {
              sourceMap: true,
              sassOptions: {
                includePaths: [ '/Users/xxx/public-web/src/styles' ]
              }
            }
          }
        ]
      },
      {
        test: /\.css$/,
        include: /(\/Users\/xxx\/public\-web\/src)/,
        use: [
          { loader: 'style-loader', options: {} },
          {
            loader: 'css-loader',
            options: {
              sourceMap: true,
              modules: { localIdentName: '[name]__[local]___[hash:base64:5]' },
              importLoaders: 1
            }
          },
          { loader: 'postcss-loader', options: { sourceMap: true } }
        ]
      },
      {
        test: /\.scss$/,
        exclude: /(\/Users\/xxx\/public\-web\/src)/,
        use: [
          { loader: 'style-loader', options: {} },
          { loader: 'css-loader', options: {} },
          { loader: 'postcss-loader', options: { sourceMap: true } },
          {
            loader: 'sass-loader',
            options: {
              sourceMap: true,
              sassOptions: {
                includePaths: [ '/Users/xxx/public-web/src/styles' ]
              }
            }
          }
        ]
      },
      {
        test: /\.css$/,
        exclude: /(\/Users\/xxx\/public\-web\/src)/,
        use: [
          { loader: 'style-loader', options: {} },
          { loader: 'css-loader', options: {} },
          { loader: 'postcss-loader', options: { sourceMap: true } }
        ]
      },
      {
        test: /\.(woff|woff2|ttf|eot|svg)(\?v=[a-z0-9]\.[a-z0-9]\.[a-z0-9])?$/,
        use: [ { loader: 'url-loader', options: { limit: 100000 } } ]
      },
      {
        test: /\.(gif|png|jpg)$/,
        use: [ { loader: 'url-loader', options: { limit: 8192 } } ]
      },
      {
        test: /\.m?js$/,
        type: 'javascript/auto',
        resolve: { fullySpecified: false }
      }
    ]
  },
  entry: {
    babelPolyfill: 'babel-polyfill',
    fetchPolyfill: 'whatwg-fetch',
    vendor: [ 'react', 'react-redux', 'react-router-dom', 'redux' ],
    app: [
      '/Users/xxx/public-web/src/main.js',
      'webpack-hot-middleware/client?path=http://192.168.4.62:3050/__webpack_hmr'
    ]
  },
  output: {
    filename: '[name].[fullhash].js',
    path: '/Users/xxx/public-web/dist',
    publicPath: 'http://192.168.4.62:3050/'
  },
  plugins: [
    DefinePlugin {
      definitions: {
        'process.env': { NODE_ENV: '"development"' },
        NODE_ENV: 'development',
        __DEV__: true,
        __PROD__: false,
        __TEST__: false,
      }
    },
    HtmlWebpackPlugin {
      options: {
        template: '/Users/xxx/public-web/src/index.html',
        templateContent: false,
        templateParameters: [Function: templateParametersGenerator],
        filename: 'index.html',
        publicPath: 'auto',
        hash: false,
        inject: 'body',
        scriptLoading: 'blocking',
        compile: true,
        favicon: false,
        minify: { collapseWhitespace: true },
        cache: true,
        showErrors: true,
        chunks: 'all',
        excludeChunks: [],
        chunksSortMode: 'auto',
        meta: {},
        base: false,
        title: 'Webpack App',
        xhtml: false
      },
      childCompilerHash: undefined,
      assetJson: undefined,
      hash: undefined,
      version: 4
    },
    HotModuleReplacementPlugin { options: {} }
  ]
}

@alexander-akait
Copy link
Member

Do you have the error when you run dev server or just simple build? Can you try to remove webpack-hot-middleware/client?path=http://192.168.4.62:3050/__webpack_hmr?

@gtwilliams03
Copy link
Author

I get the error when I run a build or dev server.

@gtwilliams03
Copy link
Author

gtwilliams03 commented Oct 13, 2020

I also get the error with or without the webpack-hot-middleware entry. Even get the error running a simple yarn install command.

@alexander-akait
Copy link
Member

I'm afraid we still have to look at reproducible test repo to fix it, hard to say why it is broken 😞

@egs33
Copy link

egs33 commented Oct 13, 2020

I was getting the same error in my project.
But, using sass package instead of node-sass solved the error. (for sass-loader)

@alexander-akait
Copy link
Member

@gtwilliams03 maybe you can provide more stack?

@alexander-akait
Copy link
Member

@egs33 Can you create minimum reproducible test repo?

@egs33
Copy link

egs33 commented Oct 13, 2020

@evilebottnawi I made a repository to reproduce. https://github.com/egs33/webpack5-cache-error

@alexander-akait
Copy link
Member

@egs33 big thanks, found the problem

@gtwilliams03
Copy link
Author

@egs33 Thank you so much! I was trying to figure out how to break the project apart to come up with a reproducible repo... Much appreciated!

@alexander-akait
Copy link
Member

@gtwilliams03 anyway try to disable cache and look on your error, you need to fix it

@gtwilliams03
Copy link
Author

@evilebottnawi I don't get any errors when I set cache: false?

@alexander-akait
Copy link
Member

Yes

@gtwilliams03
Copy link
Author

In my OP, I don't get any errors with cache: false. Never have. That's what has baffled me.

@alexander-akait
Copy link
Member

@gtwilliams03 this problem happens only when you have resolving errors

@gtwilliams03
Copy link
Author

gtwilliams03 commented Oct 13, 2020

Sorry for asking a dumb question, but how do I see the resolving errors when they don't show up in the terminal? I was actually just looking at the ResolverCachePlugin code and seeing if I could log some details in there...

@alexander-akait
Copy link
Member

@gtwilliams03 it should be shown in stats or in terminal if you use webpack-cli

@gtwilliams03
Copy link
Author

It seems to be failing before the stats get returned.

@alexander-akait
Copy link
Member

@gtwilliams03 maybe do you can create reproducible repo too? I want to investigate, maybe we have two different errors 😄

@gtwilliams03
Copy link
Author

I am still trying to figure out what module isn't resolving. The webpack-cli is dying before I can get meaningful output.

58% building 7/8 entries 3440/3600 dependencies 727/939 modules[webpack-cli] Promise rejection: TypeError: Cannot read property 'length' of undefined

@sokra
Copy link
Member

sokra commented Oct 14, 2020

I wonder why webpack-cli suppresses the stack trace...

@gtwilliams03
Copy link
Author

gtwilliams03 commented Oct 14, 2020

Somehow there is an undefined value getting passed into the ResolverCachePlugin so line 41 in enhanced-resolve/lib/util/path throws an error because p is not a string:

const getType = p => {
	switch (p.length) { // <- line 41
		case 0:
			return PathType.Empty;
...

I changed this line to:

const getType = (p = '') => { // <- changed line
	switch (p.length) { 
		case 0:
			return PathType.Empty;
...

and it works fine. No idea what path I have in my project that is creating the undefined value. Submitted a pull request to enhanced-resolve to address this edge case.

@sokra
Copy link
Member

sokra commented Oct 14, 2020

There shouldn't be a undefined value there. Seems like something is passing undefined to resolve. Maybe you are able to track this down by inserting a if(!request) somewhere higher in the stack trace. Probably a loader via getResolve() or resolve (see NormalModule.js createLoaderContext.

@joakimriedel
Copy link

If this is a resolving problem - could someone please elaborate or post a link on how to debug and find the eventual culprit? I have a fully working build, no errors or warnings (unless I enable filesystem cache with path to config that is..), no runtime errors, but still can't enable file system cache due to this issue.

@alexander-akait
Copy link
Member

@joakimriedel interesting, can you provide reproducible test repo?

@joakimriedel
Copy link

joakimriedel commented Oct 22, 2020

@evilebottnawi I'll try my best, it's a pretty big project evolved during many years and versions of Webpack so I'll need to break it down a bit first. During the last hour, I got at least the following findings;

At this line: https://github.com/webpack/enhanced-resolve/blob/0f51a8cf62b47cde4f57977cf4a205d832f8da69/lib/ParsePlugin.js#L33

the request object is supposed to have a request key (request.request) but this is the request object sent:

{"_ResolverCachePluginCacheMiss":true,"context":{},"path":"C:/Users/<redacted>/wwwroot/src/css"}

This lead me to put a debug log at this line: https://github.com/webpack/enhanced-resolve/blob/0f51a8cf62b47cde4f57977cf4a205d832f8da69/lib/Resolver.js#L398

if (/\/src\/css$/.test(request.path)) {
				console.log(JSON.stringify(hook));
				console.log(JSON.stringify(request));
				console.log(JSON.stringify(message));
			}

Which lets me see earlier in the process that the mysterious path comes from resolving bootstrap/scss/bootstrap which I do within a scss file like this:

/* bootstrap scss bundle */
@import "~bootstrap/scss/bootstrap";

using the following loader configuration

{
          test: /\.scss$/,
          use: [
            {
              loader: "style-loader", // injects css into DOM
            },
            {
              loader: "css-loader",
              options: { sourceMap: !env.production, importLoaders: 1 },
            },
            {
              loader: "postcss-loader",
              options: {
                postcssOptions: {
                  plugins: [
                    [
                      "postcss-preset-env",
                      {
                        // Options
                      },
                    ],
                  ],
                },
                sourceMap: !env.production,
              },
            },
            {
              loader: "sass-loader",
              options: {
                sourceMap: !env.production,
                sassOptions: {
                  outputStyle: "expanded", // keeps comments, such as autoprefixer commands, in output css file
                },
              },
            },
          ],
        },

I suspect some combination of Bootstrap and Webpack and sass-loader is involved. I will need further time to generate a repo, but perhaps others like @johnthecat or @gtwilliams03 can confirm if they also use Bootstrap in their configuration?

@jdelStrother
Copy link
Contributor

I'm seeing similar issues, and also have a .scss file containing:

@import "~bootstrap/scss/_functions.scss";
@import "~bootstrap/scss/_variables.scss";

@alexander-akait
Copy link
Member

Thanks I will look at this in near future, a lot of issues 😞

@alexander-akait
Copy link
Member

alexander-akait commented Oct 22, 2020

Hmm, it looks like there is no error in webpack, problem with sass-loader, webpack just generate ugly error, WIP

@gtwilliams03
Copy link
Author

gtwilliams03 commented Oct 22, 2020

@jdelStrother @joakimriedel Yes - my project also contains bootstrap and react-bootstrap. I believe that I resolved these issues by replacing node-sass with sass in the project. And you may want to try and remove the ~ at the beginning of your css path that you are trying to import.

@joakimriedel
Copy link

joakimriedel commented Oct 22, 2020

I'm sorry for the bootstrap red herring. It turned out to be fontawesome.

I have a repro here: https://github.com/joakimriedel/webpack-cache-bug-repro

Building this repro will show error. Remove cache from config - no error - builds just fine.

@alexander-akait
Copy link
Member

alexander-akait commented Oct 22, 2020

Yes, I found bug, two problems:

  • bug in sass-loader
  • ugly error from webpack when you run:
const resolve = loaderContext.getResolve(options); 

resolve(context,  undefined);
// or resolve(undefined,  undefined)

WIP on first


I even can tell you why there is an error with node-sass and no problems with sass 😄

@alexander-akait
Copy link
Member

@alexander-akait

This comment has been minimized.

@joakimriedel
Copy link

joakimriedel commented Oct 22, 2020

@evilebottnawi can confirm sass-loader 10.0.4 solves the issue I've had with the cache, webpack 5 feels rock solid now! 🎉

In my real project, compile time went from 14440 ms to 1667 ms using the filesystem cache. (on a threadripper/nvme m.2)

I'm really curious about the small change to bring the compile time even further down?

@alexander-akait

This comment has been minimized.

@joakimriedel

This comment has been minimized.

@alexander-akait

This comment has been minimized.

@joakimriedel

This comment has been minimized.

@drewlustro
Copy link

Is this issue fixed for enhanced-resolve ? I'm still experiencing it.

@alexander-akait
Copy link
Member

@drewlustro Yes (webpack/enhanced-resolve#261), but you will have error in this case, so we need to find loader with problems, can you provide config/minimum reproducible test repo

@alexander-akait
Copy link
Member

Fixed in both places (update deps to latest, i.e. sass-loader and enhanced-resolve), please leave feedback

@alexander-akait
Copy link
Member

@joakimriedel Can you try https://github.com/webpack-contrib/terser-webpack-plugin/releases/tag/v5.0.1 and provde some feedback on performance? Try it on node@12 or node@14

@joakimriedel

This comment has been minimized.

@alexander-akait

This comment has been minimized.

sokra added a commit that referenced this issue Oct 26, 2020
@phantodev
Copy link

I JUST UPGRADE WEBPACK in my PROJECT and works fine!

@PlanetPush
Copy link

This issue happened for me when path is lower case "c:"

This can be seen by putting a conditional breakpoint in the paths.map function in the method "apply(resolver)" inside "ehanced-resolve/lib/ModulesInHierarchicalDirectriesPlugin.js"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

10 participants