Repository navigation
Illegal invocation calling window.getComputedStyle #135
Description
Activity
maybe this is caused by angular v.12.2.x. I have the same problem, after updating angular version
I have the same problem, after updating from Angular 11.2.5 to 12.2.0.
Solved it by using this hack.
Install this package "replace-in-file",
Then create a node script to execute before build.`const replace = require('replace-in-file');
const options = {
files: './node_modules/preboot/fesm2015/preboot.js',
from: 'gcs(serverView).getPropertyValue('display') || 'block';',
to: 'serverView ? (gcs(serverView).getPropertyValue('display') || 'block') : 'block';'
};try {
const results = replace.sync(options);
console.log('Replacement results:', results);
}
catch (error) {
console.error('Error occurred:', error);
}
`Then add a new command to package.json
"fix_minify": "node ./node_scripts/fixMinify.js"Use it before the build
"build:ssr": "npm run fix_minify && ng build --configuration production --localize && ng run URProject:server:productionI think the issue is caused because Angular 12 uses another minifier, that is "Terser", before it was Uglify i think.
It is caused by 12.2.0. It was fine with 12.1.4.
Reacted by Julien Saguet, Rick van der Meij and kumarsetu1111I encountered the same issue when migrating to 12.2.5.
@CaerusKaru, @alan-agius4 have you seen this issue ?
For information:
No error is present with"@angular-devkit/build-angular": "12.2.0-next.0"
Error occurs starting from"@angular-devkit/build-angular": "12.2.0-next.2"Tested with all other packages set to 12.2.5
Reacted by maximegasqueI have the same issue after migration to latest angular
12.2.xCan confirm downgrading back to 12.1.4 solves the issue for me now, waiting for an update
Seems like "Preboot" is not maintained anymore
Reacted by Sam Lin and otoany news about this issue?
Reacted by ABDULLILAH and kumarsetu1111Reacted by Leif MarcusDoes anyone have a minimal reproduction we can investigate? We're in the process of cleaning up the repo and bringing it up to date, but it's hard to say what the issue is here without a firm reproduction.
Reacted by Julien Saguet, Julien and William LahtiMinimal reproduction: https://github.com/jakubsobel/angular12-preboot-issue
I've created a new angular app usingng new. Thenng add @nguniversal/express-engineand then followed https://github.com/angular/preboot#installation.
Runningnpm run build:ssrand thennpm run serve:ssris causingIllegal invocation:
Reacted by wdworak, ABDULLILAH, msobolewski94, kumarsetu1111, l-moveshelf, Julien Saguet, nagavenkateshK, Gary Lockett, Nicholas Confer, Julien and 2 moreany updates on this ?
Having the same issue here on
12.2.x.@CaerusKaru any update about this issue?
I submitted a fix in this PR: #146
It seems the error comes from a scope issue.
Something in the build must have changed starting from 12.2Let's hope it will be checked soon by @CaerusKaru as this error is also blocking for Angular 13 migration
Reacted by wdworak, jakubsobel, Pavel Razuvalau, Julien, Sam Lin and William LahtiReacted by David Bowdoin1 remaining item
Problem still present in Angular 13
@boban984 's replace script did not solve it, it does not contain the same replacement as PR #146 .
This is an updated version of the script:
fix_minify.js:
const replace = require('replace-in-file'); const options = { files: [ './node_modules/preboot/__ivy_ngcc__/fesm2015/preboot.js', './node_modules/preboot/fesm2015/preboot.js', './node_modules/preboot/esm2015/api/event.replayer.js', './node_modules/preboot/bundles/preboot.umd.js', './node_modules/preboot/bundles/preboot.umd.min.js', ], from: `getComputedStyle: window.getComputedStyle`, to: `getComputedStyle: (element, pseudoElt) => window.getComputedStyle(element, pseudoElt)` }; try { const results = replace.sync(options); console.log('Replacement results:', results); } catch (error) { console.error('Error occurred:', error); }Took a while. for me to figure out, but after installing this script, you need to clear an Angular build cache:
rm -Rf .angular/cache node fix_minify.jsAfter that, it worked for me (confirming #146 will provide the fix)
Reacted by Boban Stojanovski, wdworak, Julien, Lukas Chladek, Linus Schwab, Martti Käärik, Sam Lin, Andrey Pelykh and Gizem SeverReacted by Sam Lin, wdworak, Julien, Andrey Pelykh and Gizem SeverReacted by Sam Lin, wdworak, Julien and Andrey PelykhI can confirm that #146 and webberig's comment resolved the issue in my case.
Hopefully it gets officially patched soon, so that the hacky node script can be removed from the codebase.any update about this issue?
Reacted by Boban StojanovskiI dont have problem with angular 13, can you test it again? what function do you call?
ok I see the problem now, basicly, the preboot canot useable sorry to say that
Reacted by JulienI removed preboot from my project as I used it only for fixing page flickering. Seems it doesn't actively maintained and instead of applying workarounds I just implemented my own solution for showing overlay. The idea is pretty simple:
app.module.ts
providers: [ { provide: APP_INITIALIZER, useFactory: fixPageFlickering, deps: [PLATFORM_ID], }, ],export function fixPageFlickering(platformId: string): () => void { return () => { if (isPlatformBrowser(platformId)) { const transitionStyles = Array.from(document.querySelectorAll('style[ng-transition]')); const serverRoot = document.body.querySelector('app-root') as HTMLElement; const clientRoot = serverRoot.cloneNode() as HTMLElement; serverRoot.setAttribute('ng-non-bindable', ''); clientRoot.style.display = 'none'; document.body.insertBefore(clientRoot, serverRoot); transitionStyles.forEach((element: HTMLElement) => { element.removeAttribute('ng-transition'); }); fromEvent(window, 'load').subscribe(() => { transitionStyles.forEach((el: HTMLElement) => el.remove()); clientRoot.style.display = 'block'; serverRoot.remove(); }); } }; }Reacted by hiepxanh, Boban Stojanovski, Ruben Allaverdyan, Dolgovec, Sam Lin, Heo and AwesomeObserverReacted by hiepxanhReacted by hiepxanhReacted by William LahtiReacted by hiepxanh and Andrey PelykhGood that really nice, i will try it
It's unclear how this is related to Angular versions, it is illegal to call getComputedStyle() with
thisother thanwindow...> window.getComputedStyle(document.body) (No error) > window.getComputedStyle.apply({}, [document.body]) Uncaught TypeError: Illegal invocationPerhaps this code path wasn't being hit at all before?
In any case, I hope the PR can be merged soon. In the mean time, it is pretty easy to apply the fix and build the package yourself (just edit lib/package.json for your package name, run
npm run build, and publish thedistfolder). I've done so on@rezonant/preboot@8.0.0, feel free to use that if you wish.- added a commit that references this issue
on May 6, 2022 @pavelrazuvalau your work is great, I used in my production build and it very smoooooooooooooooooooooooooooooooth
any news about this issue?
I removed preboot from my project as I used it only for fixing page flickering. Seems it doesn't actively maintained and instead of applying workarounds I just implemented my own solution for showing overlay. The idea is pretty simple:
app.module.ts
providers: [ { provide: APP_INITIALIZER, useFactory: fixPageFlickering, deps: [PLATFORM_ID], }, ],export function fixPageFlickering(platformId: string): () => void { return () => { if (isPlatformBrowser(platformId)) { const transitionStyles = Array.from(document.querySelectorAll('style[ng-transition]')); const serverRoot = document.body.querySelector('app-root') as HTMLElement; const clientRoot = serverRoot.cloneNode() as HTMLElement; serverRoot.setAttribute('ng-non-bindable', ''); clientRoot.style.display = 'none'; document.body.insertBefore(clientRoot, serverRoot); transitionStyles.forEach((element: HTMLElement) => { element.removeAttribute('ng-transition'); }); fromEvent(window, 'load').subscribe(() => { transitionStyles.forEach((el: HTMLElement) => el.remove()); clientRoot.style.display = 'block'; serverRoot.remove(); }); } }; }Can you explain the logic behind this? I have tried integrating the same, however post-deployment it fails to work. It works on local serving however.
Reacted by Boban Stojanovskiit basicly do the same as preboot do:
- render html with no js
- angular jump in, remove previous html,
- after some milisecond, rerender the html, and replace it => this cause flick
The solution: - render html with no js
- angular jump in, rerender the html
- after some milisecond, rerender the html, and replace it => this cause flick
===> so we not remove it too soon, we just keep it there until angular ready
tested on https://awread.vn using angular 14
Reacted by Sam Lin and Hamza MoiyadiReacted by Caleb WebberBeautiful
Thanks @hiepxanh !
I included the PrebotModule in an Angular 12 project and I found that the following line breaks, because the call to
getComputedStyleis Illegal.preboot/src/lib/api/event.replayer.ts
Line 146 in 022ce61
The
getComputedStyleobject is set here:preboot/src/lib/api/event.replayer.ts
Line 21 in 022ce61
What is the current behavior?
Currently it throws an error and breaks the swapping of the root application.
If the current behavior is a bug, please provide the steps to reproduce and if possible a minimal demo of the problem by
What is the expected behavior?
Should not fail when running in the browser. I would suggest to add
.bind(window)to the declaration.Please tell us about your environment: