Closed andreialecu closed 2 years ago
Expected, something try to get content there is not content, replaced after writing by webpack, please wait the answer of angular team, we can't fix it on our side, sorry
Thanks, I opened https://github.com/angular/angular-cli/issues/22237 as well.
@alexander-akait after some discussion with an Angular team member in the issue mentioned above, it seems that they don't think this problem is on their side.
The stacktrace only mentions webpack
from top to bottom, and I noticed that if I delete the webpack
cache the problem goes away.
Would you mind taking a look at the discussion there? Thanks!
@andreialecu Can you create reproducible test repo?
Unfortunately no, this is a huge project and it seems to be occurring very randomly as also noted in: https://github.com/angular/angular-cli/issues/22237#issuecomment-980102449 where simply re-cloning got rid of the error.
The key part is probably figuring out why SizeOnlySource
is being compared to a RawSource
and how it ends up in that state. I'm hoping there's an easy way to simply audit the code based on that information.
I am afraid without more information, nobody can help with the problem, do you have enabled cache, can you try to disable, how often it happens? Is it watch/dev server/single build?
Currently it's not happening in my project any more.
But it clears up after removing the cache. It also clears up randomly after messing with package.json dependencies.
However it also randomly comes back. I've had this come and go several times over the last few days.
Once it starts happening again I'll archive the project so I have a reproduction.
Thanks
This kind of error usually happens when trying to emit assets after the compiler has already written the assets to the output directory. (After writing webpack replaces the assets with SizeOnlySources, which drops the content for memory reasons)
From the stack trace it looks like a child compiler finishes very later and tries to emits its assets to the parent compiler.
So I think the problem is that somewhere a child compiler is started, but not correctly awaited for completion. That makes it timing dependent when the assets are emitted to the parent compiler, which could randomly cause this error.
@sokra from my observations I think your assumptions are correct.
When this was occurring, the process was as follows:
I'm not sure what the reason for the double compilation is. Might be something internal to Angular.
The screenshot I referred to is in this comment: https://github.com/angular/angular-cli/issues/22237#issuecomment-980074468
Angular then automatically starts a second compilation which usually takes a second or so
I think this shouldn't be happening, do you have custom plugins?
@andreialecu Anyway I strong recommend do not close https://github.com/angular/angular-cli/issues/22237, I'm almost sure that the problem is on their side, no one except angular users faced with it (this is a pretty clear hint)
From the angular issue it sounds a bit like that might be related to css build. A font file could be referenced by css child compiler and main compiler. Is angular using mini-css?
@sokra, yeah we are using mini-css
.
Will be great to see more items in stack trace...
@alexander-akait for some reason that's the entire stack trace (the part after ✔ Compiled successfully.
is my own logging) :
✔ Compiled successfully.
fontawesome-webfont.eot SizeOnlySource { _size: 165742 } RawSource {
_valueIsBuffer: true,
_value: <Buffer 6e 87 02 00 ac 86 02 00 01 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 90 01 00 00 00 00 4c 50 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ... 165692 more bytes>,
_valueAsBuffer: <Buffer 6e 87 02 00 ac 86 02 00 01 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 90 01 00 00 00 00 4c 50 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ... 165692 more bytes>,
_valueAsString: undefined
}
.../node_modules/webpack-sources/lib/SizeOnlySource.js:16
return new Error(
^
Error: Content and Map of this Source is not available (only size() is supported)
at SizeOnlySource._error (.../node_modules/webpack-sources/lib/SizeOnlySource.js:16:10)
at SizeOnlySource.buffer (.../node_modules/webpack-sources/lib/SizeOnlySource.js:30:14)
at _isSourceEqual (.../node_modules/webpack/lib/util/source.js:21:51)
at isSourceEqual (.../node_modules/webpack/lib/util/source.js:43:17)
at Compilation.emitAsset (.../node_modules/webpack/lib/Compilation.js:4156:6)
at .../node_modules/webpack/lib/Compiler.js:546:28
at .../node_modules/webpack/lib/Compiler.js:1127:17
at eval (eval at create (.../node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:13:1)
at runMicrotasks (<anonymous>)
at processTicksAndRejections (node:internal/process/task_queues:96:5)
The terminal process "zsh '-c', 'yarn run start'" terminated with exit code: 1.
I'm not sure if this is in any way helpful, but once it starts occurring it seems to always be the same file. The only place that file is referenced is through the font-awesome
npm package:
https://unpkg.com/font-awesome@4.7.0/scss/_path.scss
Notice how it's listed twice, once with a query string. I took a look through webpack sources and I notice that there's some logic related to query strings: https://github.com/webpack/webpack/blob/122db57e7bb0ddb8327b37eeaa0adb9bd5135962/lib/Compiler.js#L592-L604
immutable
seem to then be used to consider whether to turn an asset into a SizeOnlySource
later below.
Running a full angular build (non watch-mode) works. It works so well actually that it seems to clear up the initial error so now I can no longer reproduce it, again. It does pop up randomly though, so I'm hoping next time I can troubleshoot it further.
Sounds like a cache problem... Do you enable cache?
Yes, the cache is enabled, I mentioned it earlier:
The stacktrace only mentions webpack from top to bottom, and I noticed that if I delete the webpack cache the problem goes away.
Can you try to increase stack trace using --stack-trace-limit
(https://nodejs.org/api/cli.html)?
Following a convo on discord with @andreialecu, it turns out that this stylesheet is actually referenced in a component and therefore it doesn’t use mini-css. I therefore suspect that this might be an issue with our plugin.
While digging into this, I stumbled upon the double incremental re-builds issue when the cache is restored. There appears to be an issue with Webpack, when loaders are not hoisted to the top level node_modules
and during watch mode.
@alan-agius4 hm, do you reinstall deps in watch mode?
No, see steps in https://github.com/webpack/webpack/issues/14911#issue-1072012492. Note, this is not related to the only size() is supported
issue. Just wanted to mention it here, since some people mentioned the double rebuild problem here.
Regarding the original issue, what I think is happening is that we are storing the assets from child compilers in a Map.
for (const { info, name, source } of childCompilation.getAssets()) {
this.assetCache.set(cacheKey, { info, name, source });
}
Later on during an incremental build, we are re-emitting these assets from cache.
for (const [, { name, source, info }] of this.assetCache) {
this._parentCompilation.emitAsset(name, source, info);
}
I suspect that in some cases, the source
is mutated to SizeOnlySources
. My 2 cents would be that in the cache we store source as string or buffer instead of the source Instance.
Ie:
this.assetCache.set(cacheKey, { info, name, source: source.source() });
And when we re-emit, we create a new RawSource everytime.
this._parentCompilation.emitAsset(name, new sources.RawSource(source), info);
hm, I think you should not store string or buffer, only sources have cache logic, so better to store them and avoid creating sources.RawSource
, because it is also bad for performance
Actually, I was wrong, at first seeing the logic here, the asset is not mutated since we are creating a new object each time, so back to square one.
Logic for child compilations is the same as for common compilations, and yes source
can be SizeOnlySource
if child compilation is cacheable, you can mark modules are not cachable to avoid this problem, but better to store source instead string or buffer, also it will be faster, maybe if you provide example of code I can help
Had a chat with @alexander-akait, which firstly I'd like to thank.
Unfortunately, we didn't find anything suspicions that could cause this issue and hence without a reproduction it would be hard to get to the bottom of this.
@alexander-akait also suggested that you can add a breakpoint/console.log here https://github.com/webpack/webpack-sources/blob/main/lib/SizeOnlySource.js#L15 and https://github.com/webpack/webpack/blob/main/lib/Compiler.js#L546.
Can you try to increase stack trace using
--stack-trace-limit
(nodejs.org/api/cli.html)?
I keep getting this error on and off, and I tried adding Error.stackTraceLimit = Infinity;
and longjohn. I'm not sure if either are supposed to work any more, but they didn't change anything.
I'm on Node 16.13.0, and this is an async unhandled promise error, which quits the process. There's a similar stack trace shown here: https://github.com/nodejs/node/issues/11865#issuecomment-850852069
I'm not sure why I can't get a longer stack trace.
In the mean time I've been trying to debug it further and I noticed that the double compilation issue in my case is caused by a missing/leftover file in angular.json
's assets
field.
It appears that a recompilation is triggered with changedFiles
just containing the path to that missing file. This is possibly an Angular issue. Not sure if https://github.com/webpack/webpack/issues/14911#issue-1072012492 is related or not. @alan-agius4 might be able to clarify (I also left additional details on Discord)
Other findings are that if I try to copy the entire project somewhere else, the error will not occur. I even tried to use rsync
to preserve file access times, without success. After inspecting the Angular cache files, it appears that full FS paths are hard-coded/baked into the cache. This may trigger an invalidation when the compilation is being ran from elsewhere, and it clears the error.
I've also been trying to add or remove various things to angular's webpack plugin without success. Once the error happens it keeps happening until the cache is invalidated.
To add to the above, I thought the error was triggered by the second compilation because it would only ever occur after it - however after removing the leftover file it now compiles just once.
The error still occurs, it just happens a second or so after ✔ Compiled successfully.
is printed by Angular.
Here's a recording. (there are some weird console.logs showing as well, from my debugging)
https://user-images.githubusercontent.com/697707/145184221-e210508a-5988-43f3-aca6-f53f841f8854.mov
@andreialecu, is it a possibility to either share your project (privately) or schedule a call so that we can debug this together?
@alan-agius4 yes, sure. Let's schedule a time via Discord.
FYI @alexander-akait https://github.com/angular/angular-cli/issues/22237#issuecomment-1013195711
Run:
rm -rf .angular
and then ng serve
Bug report
I'm running into
Error: Content and Map of this Source is not available (only size() is supported)
with Angular.This seems to have been reported in various other places recently: https://stackoverflow.com/questions/70066980/angular-12-content-and-map-of-this-source-is-not-available-only-size-is-suppo
What is the current behavior?
If the current behavior is a bug, please provide the steps to reproduce.
I don't have a clear reproduction, however I was able to add some logs in
emitAsset
here, which is part of the stack trace: https://github.com/webpack/webpack/blob/14582fc41504595b04f01561ea19d27391d6b9ac/lib/Compilation.js#L4171-L4176I added:
The output before the crash is:
It always seems to crash on the same
eot
file. Notice thatthis.assets[file]
for this file is aSizeOnlySource
.What is the expected behavior?
No crash.
Other relevant information: webpack version: 5.60.0 Node.js version: 16.13.0 Operating System: MacOS 11.4 Additional tools: Angular 13.0.1