Alt nytt i Babel 7 og Webpack 4

Alt nytt i Babel 7 og Webpack 4

Nye versjoner av de kanskje mest brukte verktøyene i frontend-verktøykassa er i ferd med å lande. Sven Anders tar en gjennomgang av hva som er nytt.

Babel 7

Babel er et verktøy som du bruker for å transpilere JavaScript-kode til en kodebase som støttes av et kjøremiljø som gjerne inkluderer en rekke gamle nettlesere. I begynnelsen het verktøyet 6to5 og var primært rettet mot transpilering av ECMAScript 6 kode til ECMAScript 5. Etterhvert som kodebasen utviklet seg ble prosjektet mer ambisiøst og gjennom et omfattende arkiv med plugins, støttes nå ikke bare ren transpilering av ECMAScript 6 men også senere utgaver av ECMAScript-spec samt en rekke foreslåtte utvidelser av språket og for eksempel også JSX som er en av hjørnesteinene i det populære biblioteket React. Merk: på norsk er innstikk det beste ordet vi har for å erstatte plugin, så det ordet bruk jeg i resten av artikkelen.

Hensikten med transpilering

Når en kodebase transpileres, altså oversettes til en annen utgave av det samme språket (ny til gammel), settes den inn i en blokk med kode som gjerne kalles en bundle, gjerne i én kjørefil, alternativt splittet opp i flere filer. Kostnaden ved å støtte moderne kode ved å transpilere til gammel er en stadig større bundle, og etterhvert som nettlesere og node-kjøremiljøet ble stadig mer moderne, så skaperne av Babel behovet for å kunne skille mellom kode som faktisk måtte transpileres og kode som det ikke lenger er nødvendig å gjøre noe med. 

Automatisk polyfill

Innstikket babel-preset-env er et relativt gammelt innstikk som automatisk legger inn støtte for funksjoner som ikke finnes i de nettleserne du spesifiserer at du vil betjene. Denne typen kode kalles for polyfill, et ord som beskriver utvidelser av JavaScript skrevet i ECMAScript 5 (og av og til enda eldre versjoner) som søker å emulere moderne kode ved bruk av eldre syntaks. Som oftest er ikke støtten 100% dekkende, men som regel er den god nok. Det finnes også en rekke tilsvarende innstikk, ofte med årstall i innstikknavnet som sier noe om hvilken språkversjon innstikket gir støtte for.

I Babel 7 fjernes alle disse innstikkene til fordel for babel-preset-env, som samtidig er blitt oppgradert og utvidet med en rekke nye funksjoner. Ved å benytte den nye valgmuligheten useBuiltIns i babel-konfigurasjonen sier du at du bare vil legge til polyfills på kode som det ikke er innebygd støtte for.  

Innstikket inkluderer alt som kommer i den årlige versjonen av EMCAScript (alt som er i stage-4 i utviklingssyklusen). Du kan også konfigurere den til å transpilere mot det miljøet du ønsker å støtte, eller multiple bygg slik at du for eksempel kan lage en versjon for Internet Explorer, en for Safari og en for øvrige.

Andre endringer i Babel 7

  • Babel innfører pakke-avgrensning (package-scoping). Det vil si at alle pakker du importerer må prefikses med @babel. Eksempelvis må babel-core importeres med @babel/core, babel-cli med @babel/cli og så videre.
  • Alle innstikk som er et forslag til ECMAScript får–proposal- i navnet. Går forslaget til stage-4 fjernes –proposal- igjen.
  • Støtte for utvidelse av innebygde konstruksjoner som Array, Error og HTMLElement gjennom innstikket @babel/transform-classes der du angir hvilke elementer du vil utvide via {builtins:[...]}.
  • Støtte for eldre versjon av Node (0.10 og 0.12) er fjernet
  • Støtte for optional chaining operator (a?.b) gjennom innstikket @babel/plugin-syntax-optional-chaining
  • Støtte for JSX fragments
  • Støtte for numerisk separator gjennom innstikket @babel/plugin-transform-numeric-separator
  • Støtte for optional catch binding (try { a } catch {}) gjennom innstikket @babel/plugin-proposal-optional-catch-binding som lar deg bruke en try/catch uten å opprette en ubrukt binding.

Webpack 4

Webpack 4 landet i slutten av februar med en stor og detaljert endringslogg som kan leses på https://github.com/webpack/webpack/releases/tag/v4.0.0. Blant hovedpunktene er fokus på ytelse, manifestert ved parallellisering og caching av arbeidet som gjøres av UglifyJS, samt at støtte for Node 4 er droppet. Det har gjort det mulig å skrive om en betydelig andel av kodebasen til moderne ES6 syntax og datastrukturer, noe som igjen har ført til bedre ytelse fordi kjøretidkjernen (V8) er optimalisert for moderne kode. Målet om full parallellisering- og cache-støtte er ikke oppnådd for versjon 4 men er et viktig mål for neste versjon.

Enklere konfigurasjon

Det har tradisjonelt vært komplekst å konfigurere en applikasjon for Webpack. Dette ble gradvis enklere i versjon 2 og 3, og trenden fortsetter i versjon 4. Det er nå fullt mulig å kompilere en app helt uten å sette opp en konfigurasjonsfil, noe de feirer med å promotere hashtaggen #0CJS.  Så lenge appen din har innslagspunktet i src/-mappen så vil Webpack opprette og kompilere en ferdig kjørefil i mappen dist/.

Dramatisk forbedret støtte for fjerning av ubrukt kode

I versjon 4 introduseres også støtte for parameteret sideEffects: false i package.json. Når dette feltet legges til så vet Webpack at bibliotekene som konsumeres ikke har noen sideeffekter, hvilket betyr at Webpack kan eliminere alle re-eksporteringer fra kodebasen din. I praksis betyr dette at hvis du importerer en eksportert modul fra et bibliotek som lodash-es så er import-kostnaden bare modulen du importerer og ikke hele biblioteket. Eksempelvis koster det 223 Kib (minimert) å importere chunk fra lodash-es i med sideEffects:true, mens det bare koster ~3 Kib med sideEffects: false. Det må kalles en signifikant gevinst. 

Webpack 4 kommer også med full støtte for JSON med tilsvarende ”død kode”-fjerning. Dersom du importerer JSON-filer hvor du bare bruker deler av innholdet så fjernes det øvrige fra den kompilerte kjørefilen.

ES6-minimering uten transpilering

Siden Webpack 4 kommer med UglifyJS2-støtte, betyr det du kan skrive kode med ES6-syntaks og minimere den uten å gå veien om en transpiler. Dette er en stor og etterlengtet funksjon som bør vekke glede hos mange. 

Nytt modulsystem

JavaScript har historisk vært det eneste modulsystemet med førsteklassestøtte i Webpack. Hele modulsystemet er nå omskrevet og fem modultyper er nå støttet:

  • javascript/auto. JavaScript med alle modulsystemer slått på (CommonJS, AMD, ESM). Dette var standarden i Webpack 3.
  • javascript/esm. ECMAScript-moduler (ESM). Standard for .mjs-filer.
  • javascript/dynamic. Bare CommonJS og AMD.
  • json. JSON-data. Standard for .json-filer.
  • webassembly/experimental. Eksperimentell støtte for .wasm-filer.

Ytterligere modultyper vil bli implementert etterhvert.

Farvel til populære innstikk

I Webpack 4 er en rekke vanlige innstikk gjort overflødige. Disse er NoEmitOnErrorsPlugin, ModuleConcatenationPlugin og NamedModulesPlugin. Alle disse slås på som standard i produksjonsmodus. Innstikket CommonChunksPlugin er fjernet helt og holdent.

Demo-prosjekt

Jeg har satt sammen et lite demo-prosjekt på https://github.com/svenanders/babel7webpack4 som viser  Babel 7-konfigurasjon sammen med Webpack 4 med en bitteliten "Hello World"-komponent.

 

Om bloggeren:
Frontendutvikler med sans for JavaScript. Glad i å snakke om programmering, og har utgitt boken ReactJS Blueprints på Packt forlag.

comments powered by Disqus