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

TypeError: Cannot read property 'get' of undefined when used with webpack 5 #1129

Closed
capaj opened this issue Dec 23, 2018 · 51 comments
Closed

Comments

@capaj
Copy link

capaj commented Dec 23, 2018

Expected behaviour

TypeError should not be thrown

Current behaviour

TypeError is thrown

Environment

capaj@capaj-i7-4771:~/git_projects/looop/project-alpha$ node -e "var os=require('os');console.log('Node.js ' + process.version + '\n' + os.platform() + ' ' + os.release())"
Node.js v8.11.4
linux 4.18.0-12-generic
capaj@capaj-i7-4771:~/git_projects/looop/project-alpha$ npm --version
6.4.1

capaj@capaj-i7-4771:~/git_projects/looop/project-alpha$ npm ls html-webpack-plugin
looop@ /home/capaj/git_projects/looop/project-alpha
└─┬ @storybook/react@4.1.2
  └─┬ @storybook/core@4.1.2
    └── html-webpack-plugin@4.0.0-beta.5 

I have webpack@5.0.0-alpha.1

/home/capaj/git_projects/looop/project-alpha/node_modules/html-webpack-plugin/lib/compiler.js:341
    const timestamp = fileTimestamps.get(fileDependency);
                                     ^

TypeError: Cannot read property 'get' of undefined
    at childCompiler.fileDependencies.some (/home/capaj/git_projects/looop/project-alpha/node_modules/html-webpack-plugin/lib/compiler.js:341:38)
    at Array.some (<anonymous>)
    at isChildCompilerCacheOutdated (/home/capaj/git_projects/looop/project-alpha/node_modules/html-webpack-plugin/lib/compiler.js:340:59)
    at Object.hasOutDatedTemplateCache (/home/capaj/git_projects/looop/project-alpha/node_modules/html-webpack-plugin/lib/compiler.js:321:16)
    at compiler.hooks.thisCompilation.tap (/home/capaj/git_projects/looop/project-alpha/node_modules/html-webpack-plugin/index.js:132:25)
    at SyncHook.eval [as call] (eval at create (/home/capaj/git_projects/looop/project-alpha/node_modules/tapable/lib/HookCodeFactory.js:19:10), <anonymous>:7:1)
    at Compiler.newCompilation (/home/capaj/git_projects/looop/project-alpha/node_modules/webpack/lib/Compiler.js:526:30)
    at hooks.beforeCompile.callAsync.err (/home/capaj/git_projects/looop/project-alpha/node_modules/webpack/lib/Compiler.js:567:29)
    at AsyncSeriesHook.eval [as callAsync] (eval at create (/home/capaj/git_projects/looop/project-alpha/node_modules/tapable/lib/HookCodeFactory.js:32:10), <anonymous>:6:1)
    at Compiler.compile (/home/capaj/git_projects/looop/project-alpha/node_modules/webpack/lib/Compiler.js:562:28)
    at compiler.hooks.watchRun.callAsync.err (/home/capaj/git_projects/looop/project-alpha/node_modules/webpack/lib/Watching.js:107:19)
    at AsyncSeriesHook.eval [as callAsync] (eval at create (/home/capaj/git_projects/looop/project-alpha/node_modules/tapable/lib/HookCodeFactory.js:32:10), <anonymous>:15:1)
    at compiler.cache.endIdle.err (/home/capaj/git_projects/looop/project-alpha/node_modules/webpack/lib/Watching.js:70:33)
    at AsyncParallelHook.eval [as callAsync] (eval at create (/home/capaj/git_projects/looop/project-alpha/node_modules/tapable/lib/HookCodeFactory.js:32:10), <anonymous>:6:1)
    at Cache.endIdle (/home/capaj/git_projects/looop/project-alpha/node_modules/webpack/lib/Cache.js:39:22)
    at Watching._go (/home/capaj/git_projects/looop/project-alpha/node_modules/webpack/lib/Watching.js:68:23)

Sorry I don't have a minimal webpack.config.js

@jantimon
Copy link
Owner

jantimon commented Dec 23, 2018

Thanks that was already mentioned here.

I don't understand completely why and how the filestamps api changed.

Could anyone please provide some insides or pull request to make html-webpack-plugin compatible with webpack 5?

Can anyone please give me some hints how and why the timestamps api changed?

I am using it here to find out wether the html template has to be recompiled.

For webpack 4 it just loops over all compilation file dependency timestamps.
Is getFileTimestamp as fast as that look up or will it add an additional fs lookup?

@sibelius
Copy link

sibelius commented Jan 5, 2019

here are another error we are getting on webpack 5

 TypeError: Cannot add property htmlWebpackPluginAlterChunks, object is not extensible
@entria/web:     at compiler.hooks.compilation.tap.compilation (/Users/sibelius/Dev/entria/entria-fullstack/node_modules/html-webpack-plugin/index.js:59:56)

you can run it here entria/entria-fullstack#46

it is using 3.2.0

@sibelius
Copy link

sibelius commented Jan 5, 2019

4.0.0-beta.5 works on our config

@jantimon
Copy link
Owner

jantimon commented Jan 6, 2019

Thanks for the feedback 👍

@jantimon jantimon closed this as completed Jan 6, 2019
@matheus1lva
Copy link

matheus1lva commented Jan 7, 2019

Although It works on the first build, as you save a file and it is on watch mode, we get the same error, more details here: entria/entria-fullstack#46 (comment) running 4.0.0-beta.5

@jantimon jantimon reopened this Jan 8, 2019
@jantimon
Copy link
Owner

jantimon commented Jan 8, 2019

Oh sorry you are right - its a breaking change of webpack 5.
I already tried to get some insides on this:

webpack/webpack#8537 (comment)

Crash after editing a JS file while webpack-dev-server watches for changes:

const timestamp = fileTimestamps.get(fileDependency);
TypeError: Cannot read property 'get' of undefined
    at childCompiler.fileDependencies.some (/node_modules/html-webpack-plugin/lib/compiler.js:341:38)

webpack-dev-server: 3.1.12 and html-webpack-plugin: 4.0.0-beta.5

Can anyone please give me some hints how and why the timestamps api changed?

I am using it here to find out wether the html template has to be recompiled.

For webpack 4 it just loops over all compilation file dependency timestamps.
Is getFileTimestamp as fast as that look up or will it add an additional fs lookup?

Maybe @sokra can help us here.

@jantimon jantimon pinned this issue Jan 8, 2019
@matheus1lva
Copy link

friendly ping @sokra

@sokra
Copy link
Contributor

sokra commented Jan 21, 2019

There is a new API in FileSystemInfo.

FileSystemInfo.createSnapshot(startTime, files, directories, missing, options, callback) creates a snapshot of the filesystem to check for validity later.

FileSystemInfo.checkSnapshotValid(snapshot, callback) checks if a the filesystem changed (for the passed files and directories) compared to the snapshot.

@jantimon
Copy link
Owner

jantimon commented Jan 21, 2019

This is the first time I see the FileSystemInfo.createSnapshot api and I must say it is impressive.
It abstracts the entire "do I have to recompile" problem in a very simple way! 👍

Will FileSystemInfo also be back ported to webpack 4 in order to help use so we can support webpack 4 and 5 with one code base?

Is a snapshot automatically created for every compilation or for every compiler?
If not is there an util to create a snapshot for all dependencies of a given compiler?

@benmccann
Copy link

benmccann commented Apr 4, 2019

@sokra do you have any thoughts on @jantimon's question #1129 (comment)?

edit: I see some of the same question also asked in webpack/webpack#8982

@jantimon
Copy link
Owner

jantimon commented May 27, 2019

@sokra added webpack/webpack#8982 to the "probably" list:

probably

lets see if this moves to yes in the next weeks.

@PutziSan
Copy link
Contributor

Hi, no matter if FileSystemInfo also comes for weppack 4, html-webpack-plugin has to be adapted for webpack 5 in any case and use the new FileSystemInfo API, right? Does this new implementation already exist somewhere, so that we can use html-webpack-plugin with webpack 5?

@jantimon
Copy link
Owner

@PutziSan that's correct do you want to start and send a pull request?

@PutziSan
Copy link
Contributor

PutziSan commented Jul 31, 2019

I had patched my packages already, but it's more quick-and-dirty:
This change-comparison reflects the changes I've made locally, so everything is working fine with Webpack 5 again. I didn't really understand the previous caching algorithm and adapted it in the easiest way for me, that's certainly not right for all cases and needs to be looked at again. Also, it doesn't fit perfectly yet, because the first time you render it, it also returns that the cache is invalid.
Unfortunately, I don't have time to understand or improve it any further. But if someone wants a (not perfect) solution with Webpack 5 for now, he can use my changes as a patch.
[edit: added some code, that I forgot to commit]

@jantimon
Copy link
Owner

@PutziSan wow cool thanks a lot I'll take a look at it! 💯

@egemon
Copy link

egemon commented Oct 17, 2019

Does anyone make it work with webpack 5?)

@RichiCoder1
Copy link

The above patch appears to work for me still for Webpack 5.0,0-beta0

@jwarkentin
Copy link

If anyone is looking for a quick solution, I can't vouch for the correctness of this but it seems to work for me. Install the patch-package NPM module and set the postinstall script as instructed. Then, create a directory named "patches" and a file named something like "html-webpack-plugin+4.0.0-beta.8.patch" with the following contents:

diff --git a/node_modules/html-webpack-plugin/lib/compiler.js b/node_modules/html-webpack-plugin/lib/compiler.js
index 8960360..2f431d7 100644
--- a/node_modules/html-webpack-plugin/lib/compiler.js
+++ b/node_modules/html-webpack-plugin/lib/compiler.js
@@ -336,9 +336,9 @@ function isChildCompilerCacheOutdated (mainCompilation, childCompiler) {
     return false;
   }
   // Check if any dependent file was changed after the last compilation
-  const fileTimestamps = mainCompilation.fileTimestamps;
+  const fileTimestamps = mainCompilation.fileSystemInfo._fileTimestamps;
   const isCacheOutOfDate = childCompiler.fileDependencies.some((fileDependency) => {
-    const timestamp = fileTimestamps.get(fileDependency);
+    const timestamp = fileTimestamps.get(fileDependency).timestamp;
     // If the timestamp is not known the file is new
     // If the timestamp is larger then the file has changed
     // Otherwise the file is still the same

Run npx patch-package and it will at least stop the build from crashing and seems to allow proper hot reloading when I edit things so far.

@elchicofrommo
Copy link

Hey team, so I did the patch locally and it worked for me but I'm not checking in my node_module into my repo so I have to re-apply every time I deploy to a new env. There has to be a better way than this while we're waiting for a solution to get pushed. I'm newish to node/npm. I suppose I could maintain my own repo of http_webpack_plugin and install that but is that the best way to go?

@AlonMiz
Copy link

AlonMiz commented Mar 18, 2020

u can use patch-packageuntil a proper fix will be available

Hey team, so I did the patch locally and it worked for me but I'm not checking in my node_module into my repo so I have to re-apply every time I deploy to a new env. There has to be a better way than this while we're waiting for a solution to get pushed. I'm newish to node/npm. I suppose I could maintain my own repo of http_webpack_plugin and install that but is that the best way to go?

@jwarkentin
Copy link

For anyone interested in an even quicker and dirtier foolproof patch, here's what I'm doing now:

  1. npm i patch-package
  2. Open package.json and add this in the scripts section:
    "postinstall": "patch-package"
  3. Create a patches directory in your project root, add a file named html-webpack-plugin+4.0.0-beta.11.patch and paste the following in the file:
diff --git a/node_modules/html-webpack-plugin/lib/compiler.js b/node_modules/html-webpack-plugin/lib/compiler.js
index a13abf3..011294d 100644
--- a/node_modules/html-webpack-plugin/lib/compiler.js
+++ b/node_modules/html-webpack-plugin/lib/compiler.js
@@ -335,6 +335,7 @@ function isChildCompilerCacheOutdated (mainCompilation, childCompiler) {
   if (!childCompiler.compilationStartedTimestamp) {
     return false;
   }
+  return true;
   // Check if any dependent file was changed after the last compilation
   const fileTimestamps = mainCompilation.fileTimestamps;
   const isCacheOutOfDate = childCompiler.fileDependencies.some((fileDependency) => {
  1. If you don't need to run an npm install and just need to apply the patch, run npx patch-package or npm run postinstall.

@elchicofrommo I added the step-by-step here for your benefit. Hope it helps!

@jantimon
Copy link
Owner

Has anyone already tried to use the new FileSystemInfo api to solve this?
Would love to release it as alpha as soon as it works out.

@saravanan10393
Copy link

even in 4.0.0-beta.14 of html-webpack plugin i am getting this error
`
/app/node_modules/html-webpack-plugin/lib/compiler.js:341
const timestamp = fileTimestamps.get(fileDependency);

  TypeError: Cannot read property 'get' of undefined
  at /app/node_modules/html-webpack-plugin/lib/compiler.js:341:38

`

is there any timeline to fix this bug. i am using v5.0.0.beta.14 of webpack.

@fivethreeo
Copy link
Contributor

I think it might be possible to do some conditionals with webpack.version to make PutziSan‘s changes backward compatible.

@fivethreeo
Copy link
Contributor

I forked this repo and cherry picked PutziSan’s changes, working on fixing tests so they pass on webpack5. If I get it fixed I will release a scoped package until changes can be incorporated in master.

@jantimon
Copy link
Owner

jantimon commented Mar 31, 2020

@fivethreeo if we have a working solution I would love to release it as html-webpack-plugin 5 alpha however the current solution is using an unsupported private feature of webpack which might break once they publish the new major

I am happy to publish it as alpha if anyone has time to develop a solution based on the new FileSystemInfo.createSnapshot proposed by the webpack core team

@fivethreeo
Copy link
Contributor

I got all tests but two to work in webpack5 with snapshot solution. But testing is a bit cumbersome since the webpack recompilation simulator does not currently support webpack5. Should the next release be backward compatible?

@fivethreeo
Copy link
Contributor

A alpha release sounds great 😀

@elchicofrommo
Copy link

I'm new to webpack and open source contributing. I'd love to help out. Where do I find the api specs? Also I've been looking around this repo for the tests but i'm not seeing them. Its probably something obvious I'm just overlooking. Any pointers?

@fivethreeo
Copy link
Contributor

They are in spec/

@ibufu
Copy link

ibufu commented Apr 1, 2020

Thank @PutziSan! I forked the version of @PutziSan and published it to npm as a temporary solution.

npm i html-webpack-plugin-compatible-5 -D

@elchicofrommo
Copy link

@jantimon are you still working on that alpha? It might be a nice intermediary until a final solution can be completed.

@fivethreeo
Copy link
Contributor

@elchicofrommo https://github.com/fivethreeo/html-webpack-plugin/tree/webpack5-dev just a testing dep needs to be updated first

@jantimon
Copy link
Owner

jantimon commented Apr 2, 2020

Wow @fivethreeo that looks amazing 👍👍

@fivethreeo
Copy link
Contributor

But regarding backward compatibility. Just keep both solutions until we deprecate webpack4?

@jantimon
Copy link
Owner

jantimon commented Apr 2, 2020

What about having two compiler.js files? One for webpack 4 and one for webpack 5?

@fivethreeo
Copy link
Contributor

fivethreeo commented Apr 2, 2020 via email

@jantimon
Copy link
Owner

jantimon commented Apr 2, 2020

Added some feedback to your pr here: #1390

@fivethreeo
Copy link
Contributor

Typescript did not like two webpack versions.

@fivethreeo
Copy link
Contributor

I think we need to do paralell releases with typescript. Unless there is a way to do dynamic typedef imports.

@jantimon
Copy link
Owner

jantimon commented Apr 9, 2020

Fixed in html-webpack-plugin 4.1.0

@jantimon jantimon closed this as completed Apr 9, 2020
@jantimon jantimon unpinned this issue Apr 9, 2020
@lock lock bot locked as resolved and limited conversation to collaborators May 20, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests