jQuery 4.0.0 è arrivato: cosa cambia davvero (breaking change inclusi) e come aggiornare senza sorprese
Il 14 gennaio 2006 John Resig presentava jQuery al BarCamp di New York. Vent’anni dopo, il team rilascia la versione finale di jQuery 4.0.0: una major release che arriva dopo un ciclo di sviluppo lungo e varie pre-release, ed è la prima “vera” major da quasi 10 anni.
Il punto chiave: jQuery 4.0.0 include breaking change, ma l’aspettativa dichiarata è che molti progetti riusciranno ad aggiornare con interventi minimi. Il salto di versione serve soprattutto a fare quello che in una minor/patch non si poteva: tagliare codice legacy, rimuovere API già deprecate, eliminare parametri interni mai documentati, e ridurre comportamenti “magici” diventati più costosi che utili.
Prima di aggiornare
Il team ha preparato una guida ufficiale all’upgrade e un rilascio del plugin jQuery Migrate per rendere la transizione più gestibile: https://jquery.com/upgrade-guide/4.0/ e https://github.com/jquery/jquery-migrate/. Se trovi problemi reali durante l’upgrade, il canale corretto è l’issue tracker: https://github.com/jquery/jquery/issues.
Dove prendere jQuery 4.0.0 (CDN e npm)
Come sempre, jQuery 4.0.0 è disponibile sul CDN ufficiale e su npm. Altri CDN terzi dovrebbero allinearsi a breve, ma i tempi dipendono dai rispettivi processi di pubblicazione.
- Build completa (non minificata): https://code.jquery.com/jquery-4.0.0.js
- Build completa (minificata): https://code.jquery.com/jquery-4.0.0.min.js
- Installazione via npm:
npm install jquery@4.0.0
Supporto browser: addio IE < 11 (e altri legacy)
Il cambiamento più “visibile” è il taglio del supporto a IE 10 e precedenti. Il team ha scelto un’uscita per fasi: qualcuno potrebbe chiedersi perché non sia stato rimosso anche IE 11 subito; la risposta è che il prossimo step è pianificato per jQuery 5.0 (vedi la discussione collegata nella PR: https://github.com/jquery/jquery/pull/5077). In 4.0, quindi, viene eliminato il codice specifico per IE più vecchi di 11.
In parallelo, vengono abbandonati anche altri browser molto datati: Edge Legacy, versioni iOS precedenti alle ultime 3, versioni Firefox precedenti alle ultime 2 (eccezione: Firefox ESR), e Android Browser. Il messaggio è chiaro: se devi supportare uno di questi target, la linea consigliata è restare su jQuery 3.x.
Compatibilità: cosa devi fare tu?
Secondo l’annuncio, non dovrebbero essere richiesti cambiamenti specifici solo per via del taglio browser. Il vero lavoro di upgrade nasce dai breaking change di API/comportamenti; se invece il tuo requisito è supportare browser esclusi, non aggiornare e resta su jQuery 3.x.
CSP e Trusted Types: jQuery più “sicuro” nei contesti moderni
jQuery 4.0 introduce supporto a Trusted Types, il meccanismo pensato per ridurre i rischi di XSS quando lavori con HTML “dinamico”. In pratica, HTML incapsulato in TrustedHTML (API documentata su MDN: https://developer.mozilla.org/en-US/docs/Web/API/TrustedHTML) può essere passato ai metodi di manipolazione jQuery senza violare la direttiva CSP require-trusted-types-for.
C’è anche un’altra modifica collegata alla CSP: in passato alcune richieste AJAX usavano già <script> per preservare attributi come crossdomain, ma ora la maggior parte delle richieste asincrone di script passa a <script> (vedi PR: https://github.com/jquery/jquery/pull/4763) per evitare errori CSP tipici degli inline script. Rimangono alcuni casi in cui si usa ancora XHR per richiedere script asincroni, ad esempio quando viene passato l’option headers (il suggerimento è usare scriptAttrs invece). L’approccio però è: usare <script> quando possibile.
Sorgente migrato a ES Modules: jQuery entra nel mondo dei bundler moderni
Una delle modernizzazioni più importanti è la migrazione del sorgente nel branch main da AMD (pattern tipico di RequireJS) a ES modules (ESM). Storicamente il sorgente era pubblicato su npm e GitHub, ma non era importabile “come modulo” senza RequireJS, che era anche il build tool preferito per impacchettare jQuery.
Ora la confezione passa a Rollup (https://rollupjs.org/introduction/) e i test vengono eseguiti anche sugli ES modules separatamente. Il risultato pratico: migliore compatibilità con toolchain moderne, workflow di sviluppo più attuali e possibilità di utilizzo nativo in browser via <script type=module>.
API deprecate rimosse: cosa sparisce e cosa usare al posto
jQuery 4.0.0 fa pulizia: diverse funzioni erano deprecate da molte versioni e vengono rimosse in questa major. In molti casi erano sempre state pensate come interne, oppure oggi hanno equivalenti nativi disponibili in tutti i browser supportati.
jQuery.isArrayjQuery.parseJSONjQuery.trimjQuery.typejQuery.nowjQuery.isNumericjQuery.isFunctionjQuery.isWindowjQuery.camelCasejQuery.nodeNamejQuery.cssNumberjQuery.cssPropsjQuery.fx.interval
L’indicazione è di migrare verso gli equivalenti nativi, ad esempio:
Array.isArray()al posto dijQuery.isArrayJSON.parse()al posto dijQuery.parseJSONString.prototype.trim()al posto dijQuery.trimDate.now()al posto dijQuery.now
La combinazione tra rimozione API deprecate e taglio del codice per i vecchi IE porta anche un risultato misurabile: oltre 3k byte (gzipped) in meno.
Metodi “solo interni” rimossi dal prototype: push/sort/splice
Da tempo il prototype di jQuery includeva metodi Array che non si comportavano come i metodi jQuery “normali” ed erano pensati esclusivamente per uso interno: push, sort, splice. In 4.0 vengono rimossi dal prototype.
Se per qualche motivo li stavi usando direttamente su una jQuery collection, l’equivalente suggerito è chiamare i metodi dell’Array prototipo esplicitamente. Esempio: sostituisci $elems.push( elem ) con:
[].push.call( $elems, elem );Ordine eventi focus/blur: ora segue la specifica W3C (breaking change reale)
Per anni i browser non sono stati d’accordo sull’ordine degli eventi legati al focus: focusin, focusout, focus, blur. jQuery aveva scelto un ordine coerente “interno”, ma oggi i browser supportati da jQuery 4.0 convergono finalmente su un ordine comune… che però è diverso da quello storico di jQuery.
Da jQuery 4.0 non viene più sovrascritto il comportamento nativo. Questo significa che tutti i browser (eccetto IE) seguono l’attuale specifica W3C, con questo ordine:
- blur
- focusout
- focus
- focusin
Nelle versioni precedenti, l’ordine jQuery era: focusout, blur, focusin, focus. Nota curiosa riportata dal team: l’unico browser ad aver seguito la vecchia specifica W3C (prima dell’aggiornamento del 2023) era Internet Explorer.
Slim build aggiornata: ancora più piccola, ma senza Deferred e Callbacks
La slim build di jQuery 4.0.0 diventa ancora più leggera: ora esclude anche Deferred e Callbacks, arrivando a circa 19,5k bytes gzipped. Deferred supportava da tempo lo standard Promises/A+ (https://promisesaplus.com/), quindi nella maggior parte dei casi puoi migrare su Promise native (disponibili in tutti i browser supportati da jQuery, tranne IE11).
Deferred offre alcune funzionalità extra che le Promise native non coprono, ma molte codebase possono essere convertite usando i metodi delle Promise. Se devi supportare IE11, l’indicazione è: usare la build principale oppure aggiungere un polyfill per le Promise.
Anche in 4.0 resta la distinzione: build completa “con tutto” e slim “senza moduli che potresti non volere”. La size oggi raramente è un collo di bottiglia, ma la slim è circa 8k gzipped byte più piccola della versione completa.
- Slim (non minificata): https://code.jquery.com/jquery-4.0.0.slim.js
- Slim (minificata): https://code.jquery.com/jquery-4.0.0.slim.min.js
Il team segnala anche che questi aggiornamenti sono già disponibili come versioni correnti su npm e Bower. Per tutti i metodi di distribuzione supportati, la pagina di riferimento resta https://jquery.com/download/.
Nota sui CDN pubblici
I CDN pubblici ricevono i file “oggi”, ma potrebbero metterci qualche giorno a pubblicarli. Se vuoi partire subito, usa il CDN ufficiale jQuery finché gli altri non si aggiornano.
Foto del reunion: 20 anni di jQuery
Per celebrare i 20 anni, parte del team si è incontrata a Dallas per un reunion; John Resig era collegato via Zoom. Il post è stato pubblicato mentre erano insieme.

Changelog completo e punti salienti tecnici (per chi deve fare audit)
Il changelog completo è disponibile qui: https://github.com/jquery/jquery/compare/3.7.1…4.0.0 (tag: 4.0.0). Qui sotto trovi l’elenco integrale delle voci pubblicate, organizzate per area, utile per fare un audit mirato su progetti complessi.
Ajax
- Don’t treat array data as binary (992a1911)
- Allow
processData: trueeven for binary data (ce264e07) - Support binary data (including FormData) (a7ed9a7b)
- Support
headersfor script transport even when cross-domain (#5142, 6d136443) - Support
nullas success functions injQuery.get(#4989, 74978b7e) - Don’t auto-execute scripts unless dataType provided (#4822, 025da4dd)
- Make responseJSON work for erroneous same-domain JSONP requests (68b4ec59)
- Execute JSONP error script responses (#4771, a1e619b0)
- Avoid CSP errors in the script transport for async requests (#3969, 07a8e4a1)
- Drop the json to jsonp auto-promotion logic (#1799, #3376, e7b3bc48)
- Overwrite s.contentType with content-type header value, if any (#4119, 7fb90a6b)
- Deprecate AJAX event aliases, inline event/alias into deprecated (23d53928)
- Do not execute scripts for unsuccessful HTTP responses (#4250, 50871a5a)
- Simplify jQuery.ajaxSettings.xhr (#1967, abdc89ac)
Attributes
- Make
.attr( name, false )remove for all non-ARIA attrs (#5388, 063831b6) - Shave off a couple of bytes (b40a4807)
- Don’t stringify attributes in the setter (#4948, 4250b628)
- Drop the
toggleClass(boolean|undefined)signature (#3388, a4421101) - Refactor val(): don’t strip carriage return, isolate IE workarounds (ff281991)
- Don’t set the type attr hook at all outside of IE (9e66fe9a)
CSS
- Fix dimensions of table
<col>elements (#5628, eca2a564) - Drop the cache in finalPropName (640d5825)
- Tests: Fix tests & support tests under CSS Zoom (#5489, 071f6dba)
- Fix reliableTrDimensions support test for initially hidden iframes (b1e66a5f)
- Selector: Align with 3.x, remove the outer
selector.jswrapper (53cf7244) - Make the reliableTrDimensions support test work with Bootstrap CSS (#5270, 65b85031)
- Make
offsetHeight( true ), etc. include negative margins (#3982, bce13b72) - Return
undefinedfor whitespace-only CSS variable values (#5120) (7eb00196) - Don’t trim whitespace of undefined custom property (#5105, ed306c02)
- Skip falsy values in
addClass( array ), compress code (#4998, a338b407) - Justify use of rtrim on CSS property values (655c0ed5)
- Trim whitespace surrounding CSS Custom Properties values (#4926, efadfe99)
- Include
show,hide&togglemethods in the jQuery slim build (297d18dd) - Remove the opacity CSS hook (865469f5)
- Workaround buggy getComputedStyle on table rows in IE/Edge (#4490, 26415e08)
- Don’t automatically add “px” to properties with a few exceptions (#2795, 00a9c2e5)
Core
- Remove obsolete workarounds, update support comments (e2fe97b7)
- Switch
$.parseHTMLfromdocument.implementationtoDOMParser(0e123509) - Fix the exports setup to make bundlers work with ESM & CommonJS (#5416, 60f11b58)
- Add more info about named exports (5f869590)
- Simplify code post browser support reduction (93ca49e6)
- Move the factory to separate exports (46f6e3da)
- Use named exports in
src/(#5262, f75daab0) - Fix regression in jQuery.text() on HTMLDocument objects (#5264, a75d6b52)
- Selector: Move jQuery.contains from the selector to the core module (024d8719)
- Drop the root parameter of jQuery.fn.init (d2436df3)
- Don’t rely on splice being present on input (9c6f64c7)
- Manipulation: Add basic TrustedHTML support (#4409, de5398a6)
- Report browser errors in parseXML (#4784, 89697325)
- Make jQuery.isXMLDoc accept falsy input (#4782, fd421097)
- Drop support for Edge Legacy (i.e. non-Chromium Microsoft Edge) (#4568, e35fb62d)
- Fire iframe script in its context, add doc param in globalEval (#4518, 4592595b)
- Exclude callbacks & deferred modules in the slim build as well (fbc44f52)
- Migrate from AMD to ES modules 🎉 (d0ce00cd)
- Use Array.prototype.flat where supported (#4320, 9df4f1de)
- Remove private copies of push, sort & splice from the jQuery prototype (b59107f5)
- Implement .even() & .odd() to replace POS :even & :odd (78420d42)
- Deprecate jQuery.trim (#4363, 5ea59460)
- Remove IE-specific support tests, rely on document.documentMode (#4386, 3527a384)
- Drop support for IE <11, iOS <11, Firefox <65, Android Browser & PhantomJS (#3950, #4299, cf84696f)
- Remove deprecated jQuery APIs (#4056, 58f0c00b)
Data
- Refactor to reduce size (805cdb43)
- Event:Manipulation: Prevent collisions with Object.prototype (#3256, 9d76c0b1)
- Separate data & css/effects camelCase implementations (#3355, 8fae2120)
Deferred
- Rename
getStackHooktogetErrorHook(#5201, 258ca1ec) - Respect source maps in jQuery.Deferred.exceptionHook (#3179, 0b9c5037)
- Rename master to primary (a32cf632)
Deprecated
- Define
.hover()using non-deprecated methods (fd6ffc5e) - Remove jQuery.trim (0b676ae1)
- Fix AMD parameter order (f810080e)
Dimensions
Docs
- Fix some minor issues in comments (e4d4dd81)
- update herodevs link in README (#5695, 093e63f9)
- Align CONTRIBUTING.md with
3.x-stable(d9281061) - Update CONTRIBUTING.md (4ef25b0d)
- add version support section to README (cbc2bc1f)
- Update remaining HTTP URLs to HTTPS (7cdd8374)
- Fix module links in the package README (ace646f6)
- update watch task in CONTRIBUTING.md (77d6ad71)
- Fix typos found by codespell (620870a1)
- remove stale gitter badge from readme (67cb1af7)
- Remove the “Grunt build” section from the PR template (988a5684)
- Remove stale badge from README (bcd9c2bc)
- Update the README of the published package (edccabf1)
- Remove git.io from a GitHub Actions comment (016872ff)
- Update webpack website in README (01819bc3)
- add link to patchwelcome and help wanted issues (924b7ce8)
- add link to preview the new CLAs (683ceb8f)
- Fix incorrect
trac-NUMBERreferences (eb9ceb2f) - remove expired links from old jquery source (#4997) (ed066ac7)
- Remove links to Web Archive from source (#4981, e24f2dcf)
- Replace
#NUMBERTrac issue references withtrac-NUMBER(5d5ea015) - Update the URL to the latest jQuery build in CONTRIBUTING.md (9bdb16cd)
- Remove the CLA checkbox in the pull request template (e1248931)
- update irc to Libera and fix LAMP dead link (175db73e)
- Update Frequently Reported Issues in the GitHub issue template (7a6fae6a)
- Change JS Foundation mentions to OpenJS Foundation (11611967)
- add SECURITY.md, show security email address (2ffe54ca)
- Fix typos (1a7332ce)
- Update the link to the jsdom repository (a62309e0)
- Use https for hyperlinks in README (73415da2)
- Remove a mention of the event/alias.js module from README (3edfa1bc)
- Update links to EdgeHTML issues to go through Web Archive (1dad1185)
- direct users to GitHub docs for cloning the repo (f1c16de2)
- Change OS X to macOS in README (5a3e0664)
- Update most URLs to HTTPS (f09d9210)
- Convert link to Homebrew from HTTP to HTTPS (e0022f23)
Effect
Effects
- Remove jQuery.fx.interval (6c2c7362)
Event
- Use
.preventDefault()in beforeunload (7c123dec) - Increase robustness of an inner native event in leverageNative (#5459, 527fb3dc)
- Avoid collisions between jQuery.event.special & Object.prototype (bcaeb000)
- Simplify the check for saved data in leverageNative (dfe212d5)
- Make trigger(focus/blur/click) work with native handlers (#5015, 6ad3651d)
- Simulate focus/blur in IE via focusin/focusout (#4856, #4859, #4950, ce60d318)
- Don’t break focus triggering after
.on(focus).off(focus)(#4867, e539bac7) - Make focus re-triggering not focus the original element back (#4382, dbcffb39)
- Don’t crash if an element is removed on blur (#4417, 5c2d0870)
- Remove the event.which shim (#3235, 1a5fff4c)
- remove jQuery.event.global (18db8717)
- Only attach events to objects that accept data — for real (#4397, d5c505e3)
- Stop shimming focusin & focusout events (#4300, 8a741376)
- Prevent leverageNative from registering duplicate dummy handlers (eb6c0a7c)
- Fix handling of multiple async focus events (#4350, ddfa8376)
Manipulation
- Make jQuery.cleanData not skip elements during cleanup (#5214, 3cad5c43)
- Generalize a test to support IE (88690ebf)
- Support $el.html(selfRemovingScript) (#5378) (#5377, 937923d9)
- Extract domManip to a separate file (ee6e8740)
- Don’t remove HTML comments from scripts (#4904, 2f8f39e4)
- Respect script crossorigin attribute in DOM manipulation (#4542, 15ae3614)
- Avoid concatenating strings in buildFragment (9c98e4e8)
- Make jQuery.htmlPrefilter an identity function (90fed4b4)
- Selector: Use the nodeName util where possible to save size (4504fc3d)
Offset
- Increase search depth when finding the ‘real’ offset parent (556eaf4a)
Release
- 4.0.0 (4f2fae08)
- remove dist files from main branch (c838cfb5)
- 4.0.0-rc.2 (97525193)
- Update AUTHORS.txt (c128d5d8)
- Fix release issues uncovered during the 4.0.0-rc.1 release (a5b0c431)
- remove dist files from main branch (9d06c6dd)
- 4.0.0-rc.1 (586182f3)
- Run
npm publishin the post-release phase (ff1f0eaa) - Only run browserless tests during the release (fb5ab0f5)
- Temporarily disable running tests on release (3f79644b)
- publish tmp/release/dist folder when releasing (#5658, a865212d)
- correct build date in verification; other improvements (53ad94f3)
- remove dist files from main branch (be048a02)
- 4.0.0-beta.2 (51fffe9f)
- ensure builds have the proper version (3e612aee)
- set preReleaseBase in config file (1fa8df5d)
- fix running pre/post release scripts in windows (5518b2da)
- update AUTHORS.txt (862e7a18)
- migrate release process to release-it (jquery/jquery-release#114, 2646a8b0)
- add factory files to release distribution (#5411, 1a324b07)
- use buildDefaultFiles directly and pass version (b507c864)
- copy dist-module folder as well (63767650)
- only published versioned files to cdn (3a0ca684)
- remove scripts and dev deps from dist package.json (7eac932d)
- update build command in Release.generateArtifacts (3b963a21)
- add support for md5 sums in windows (f088c366)
- remove the need to install grunt globally (b2bbaa36)
- upgrade release dependencies (967af732)
- Remove an unused chalk dependency (bfb6897c)
- Use an in-repository dist README fixture (358b769a)
- Update AUTHORS.txt (1b74660f)
- update AUTHORS.txt (cf9fe0f6)
Selector
- Remove the workaround for
:has; test both on iPhone & iPad (65e35450) - Properly deprecate
jQuery.expr[ ":" ]/jQuery.expr.filters(329661fd) - Make
selector.jsmodule depend onattributes/attr.js(#5379, e06ff088) - Eliminate
selector.jsdepenencies from various modules (e8b7db4b) - Re-expose jQuery.find.{tokenize,select,compile,setDocument} (#5259, 338de359)
- Stop relying on CSS.supports( “selector(…)” ) (#5194, 68aa2ef7)
- Backport jQuery selection context logic to selector-native (#5185, 2e644e84)
- Make selector lists work with
qSAagain (#5177, 09d988b7) - Implement the
uniqueSortchainable method (#5166, 5266f23c) - Re-introduce selector-native.js (4c1171f2)
- Manipulation: Fix DOM manip within template contents (#5147, 3299236c)
- Drop support for legacy pseudos, test custom pseudos (8c7da22c)
- Use jQuery
:hasifCSS.supports(selector(...))non-compliant (#5098, d153c375) - Remove the “a:enabled” workaround for Chrome <=77 (c1ee33ad)
- Make empty attribute selectors work in IE again (#4435, 05184cc4)
- Use shallow document comparisons in uniqueSort (#4441, 15750b0a)
- Add a test for throwing on post-comma invalid selectors (6eee5f7f)
- Make selectors with leading combinators use qSA again (ed66d5a2)
- Use shallow document comparisons to avoid IE/Edge crashes (#4441, aa6344ba)
- reduce size, simplify setDocument (29a9544a)
- Leverage the :scope pseudo-class where possible (#4453, df6a7f7f)
- Bring back querySelectorAll shortcut usage (cef4b731)
- Inline Sizzle into the selector module (47835965)
- Port Sizzle tests to jQuery (79b74e04)
Support
Traversing
- Fix
contents()on<object>s with children in IE (ccbd6b93) - Fix
contents()on<object>s with children (#4384, 4d865d96)
Takeaway pratico: come approcciare l’upgrade in una codebase reale
- Leggi la guida ufficiale: https://jquery.com/upgrade-guide/4.0/
- Integra (se serve) jQuery Migrate: https://github.com/jquery/jquery-migrate/
- Cerca e rimuovi l’uso delle API eliminate (es.
jQuery.trim,jQuery.parseJSON,jQuery.now). - Controlla eventuali dipendenze “strane” dal prototype (uso di
push/sort/splicesu jQuery collection). - Verifica test e UX dove hai logiche sensibili a focus/blur: l’ordine eventi è cambiato e ora segue W3C.
- Se usi slim build, verifica se ti servivano Deferred/Callbacks: in 4.0 la slim non li include e dovrai migrare a Promise o usare la build completa.
- Se hai requisiti di supporto browser legacy (IE10, Edge Legacy, Android Browser, iOS molto vecchi, Firefox molto vecchi), resta su jQuery 3.x.
Riferimenti / Fonti
- jQuery 4.0.0
- jQuery Upgrade Guide: 4.0
- jquery/jquery-migrate
- jQuery issues
- jQuery 4.0.0 full changelog (compare 3.7.1…4.0.0)
- TrustedHTML – MDN Web Docs
- Rollup introduction
- Promises/A+
- jQuery download
- jQuery PR: Switch most asynchronous script requests to use <script> tags
- jQuery PR: Plan to remove IE11 support in jQuery 5.0
Giulia Romano
Appassionata di data science e machine learning. Mi interessano Python, TensorFlow e la visualizzazione dei dati. Credo nel processo decisionale basato sui dati.
Tutti gli articoli