Nastavení projektu ES6 pomocí Babelu a webpacku
V tomto článku se podíváme na vytvoření nastavení sestavení pro práci s moderním JavaScriptem (běžícím ve webových prohlížečích) pomocí Babelu a webpacku.
To je nutné k zajištění toho, aby byl náš moderní kód JavaScriptu kompatibilní s širší škálou prohlížečů, než by tomu mohlo být jinak.
JavaScript se stejně jako většina webových technologií neustále vyvíjí. Za starých dobrých časů jsme mohli do stránky vložit pár značek <script>
, možná zahrnout jQuery a pár zásuvných modulů a mohli jsme pracovat.
Od zavedení ES6 se však situace postupně komplikuje. Podpora novějších funkcí jazyka ze strany prohlížečů je často nejednotná a s rostoucími ambicemi aplikací v JavaScriptu začínají vývojáři k organizaci kódu používat moduly. To zase znamená, že pokud dnes píšete moderní JavaScript, musíte do svého procesu zavést krok sestavení.
Jak vidíte z odkazů níže, převodem dolů z ES6 na ES5 se dramaticky zvyšuje počet prohlížečů, které můžeme podporovat.
- Kompatibilita s ES6
- Kompatibilita s ES5
Účelem systému sestavení je automatizovat pracovní postup potřebný k tomu, aby byl náš kód připraven pro prohlížeče a produkci. To může zahrnovat kroky, jako je transpilování kódu do odlišného standardu, kompilace Sass do CSS, sdružování souborů, minifikace a komprese kódu a mnoho dalších. Aby bylo zajištěno jejich důsledné opakování, je zapotřebí systém sestavení, který tyto kroky spustí ve známé posloupnosti z jediného příkazu.
Předpoklady
Abyste mohli postupovat dále, budete muset mít nainstalovaný Node.js i npm (dodávají se společně). Pro správu instalace Node doporučuji používat správce verzí, jako je nvm (zde je návod), a pokud byste chtěli pomoci s ovládáním npm, podívejte se na začátečnický návod k npm od SitePointu.
Nastavení
Vytvořte si někde v počítači kořenovou složku a přejděte do ní z terminálu/příkazového řádku. Bude to vaše složka <ROOT>
.
Vytvořte soubor package.json
s tímto:
npm init -y
Poznámka: Příznak -y
vytvoří soubor s výchozím nastavením a znamená, že nemusíte vyplňovat žádné obvyklé údaje z příkazového řádku. Pokud chcete, můžete je později změnit v editoru kódu.
Ve složce <ROOT>
vytvořte adresáře src
, src/js
a public
. Do adresáře src/js
budeme umisťovat nezpracovaný zdrojový kód a ve složce public
skončí transpilovaný kód.
Transpilace pomocí Babel
Abychom mohli začít, nainstalujeme si babel-cli, který poskytuje možnost transpilovat ES6 do ES5, a babel-preset-env, který nám umožní transpilovaný kód zacílit na konkrétní verze prohlížečů.
npm install babel-cli babel-preset-env --save-dev
V souboru package.json
byste nyní měli vidět následující:
"devDependencies": { "babel-cli": "^6.26.0", "babel-preset-env": "^1.6.1"}
Když jsme v souboru package.json
, změňme část scripts
takto:
"scripts": { "build": "babel src -d public"},
To nám dává možnost volat Babel prostřednictvím skriptu, a ne pokaždé přímo z terminálu. Pokud se chcete dozvědět více o skriptech npm a o tom, co umí, podívejte se na tento návod SitePoint.
Nakonec, než budeme moci otestovat, zda Babel dělá svou práci, musíme vytvořit konfigurační soubor .babelrc
. Na ten se bude náš balíček babel-preset-env
odkazovat, pokud jde o parametry transpile.
Vytvořte ve svém adresáři <ROOT>
nový soubor s názvem .babelrc
a vložte do něj následující:
{ "presets": } } ] ]}
Tímto nastavíte Babel na transpile pro poslední dvě verze každého prohlížeče a navíc Safari ve verzi 7 nebo vyšší. Další možnosti jsou k dispozici podle toho, které prohlížeče potřebujete podporovat.
Po uložení si nyní můžeme vše vyzkoušet pomocí ukázkového souboru JavaScriptu, který používá ES6. Pro účely tohoto článku jsem upravil kopii leftpadu tak, aby na několika místech používala syntaxi ES6: šablonové literály, šipkové funkce, const a let.
Ulož to jako src/js/leftpad.js
a z terminálu spusť následující příkaz:
npm run build
Pokud je vše tak, jak má být, ve složce public
byste nyní měli najít nový soubor s názvem js/leftpad.js
. Pokud jej otevřete, zjistíte, že již neobsahuje žádnou syntaxi ES6 a vypadá takto:
Organizace kódu pomocí modulů ES6
Modul ES6 je soubor jazyka JavaScript obsahující funkce, objekty nebo primitivní hodnoty, které chcete zpřístupnit jinému souboru jazyka JavaScript. Z jednoho export
a do druhého import
. Každý seriózní moderní projekt v jazyce JavaScript by měl uvažovat o použití modulů. Umožňují rozdělit kód na samostatné jednotky, a tím usnadňují údržbu; pomáhají vyhnout se znečištění jmenného prostoru; a pomáhají učinit váš kód přenositelnějším a opakovaně použitelným.
Zatímco většina syntaxe ES6 je v moderních prohlížečích široce dostupná, u modulů tomu tak zatím není. V době psaní tohoto článku jsou k dispozici v prohlížečích Chrome, Safari (včetně nejnovější verze pro iOS) a Edge; ve Firefoxu a Opeře jsou skryty za příznakem; a nejsou (a pravděpodobně nikdy nebudou) k dispozici v IE11 ani ve většině mobilních zařízení.
V další části se podíváme na to, jak můžeme moduly integrovat do našeho nastavení sestavení.
Export
Klíčové slovo export je to, co nám umožňuje zpřístupnit naše moduly ES6 jiným souborům, a nabízí nám k tomu dvě možnosti – pojmenované a výchozí. S pojmenovaným exportem můžeme mít více exportů na modul a s výchozím exportem pouze jeden na modul. Pojmenované exporty jsou užitečné zejména tam, kde potřebujeme exportovat několik hodnot. Například můžete mít modul obsahující několik užitečných funkcí, které je třeba zpřístupnit na různých místech vašich aplikací.
Přeměníme tedy náš soubor leftPad
na modul, který pak můžeme vyžadovat v druhém souboru.
Pojmenovaný export
Pro vytvoření pojmenovaného exportu přidáme na konec souboru leftPad
následující příkaz:
export { leftPad };
Můžeme také odstranit deklaraci "use strict";
z horní části souboru, protože moduly standardně běží ve striktním režimu.
Defultní export
Jelikož v souboru leftPad
je pouze jediná funkce, která má být exportována, může být ve skutečnosti dobrým kandidátem na použití export default
místo toho:
export default function leftPad(str, len, ch) { ...}
Znovu můžeme odstranit deklaraci "use strict";
z vrcholu souboru.
Import
Chceme-li využít exportované moduly, musíme je nyní importovat do souboru (modulu), ve kterém je chceme použít.
Při volbě export default
lze exportovaný modul importovat pod libovolným názvem, který si zvolíte. Například modul leftPad
lze importovat takto:
import leftPad from './leftpad';
Nebo jej lze importovat pod jiným jménem, například takto:
import pineapple_fritter from './leftpad';
Funkčně budou oba způsoby fungovat úplně stejně, ale samozřejmě má smysl použít buď stejné jméno, pod kterým byl exportován, nebo něco, co umožní pochopitelný import – třeba tam, kde by exportované jméno kolidovalo s jiným jménem proměnné, která již v přijímajícím modulu existuje.
Při pojmenované možnosti exportu musíme modul importovat pod stejným jménem, pod jakým byl exportován. Pro náš příklad bychom modul importovali podobným způsobem, jaký jsme použili u syntaxe export default
, ale v tomto případě musíme importovaný název obalit kudrnatými závorkami:
import { leftPad } from './leftpad';
Závorky jsou u pojmenovaného exportu povinné, a pokud je nepoužijeme, dojde k selhání.
V případě potřeby je možné název pojmenovaného exportu při importu změnit, a abychom tak mohli učinit, musíme naši syntaxi trochu upravit pomocí syntaxe import as
. Stejně jako u export
existuje řada způsobů, jak to udělat, všechny jsou podrobně popsány na stránce o importu MDN.
import { leftPad as pineapple_fritter } from './leftpad_es6';
Znovu připomínám, že změna názvu je trochu nesmyslná, ale ilustruje to, že je lze změnit na cokoli. Měli byste vždy dodržovat správné postupy při pojmenovávání, pokud samozřejmě nepíšete rutiny pro přípravu receptů na bázi ovoce.
Použití exportovaného modulu
Pro využití exportovaného modulu leftPad
jsem vytvořil následující soubor index.js
ve složce src/js
. Zde procházím ve smyčce pole sériových čísel a předřazuji jim nuly, aby se z nich stal osmiznakový řetězec. Později toho využijeme a vypíšeme je do prvku uspořádaného seznamu na stránce HTML. Všimněte si, že tento příklad používá výchozí syntaxi exportu:
Stejně jako dříve spusťte sestavovací skript z adresáře <ROOT>
:
npm run build
Babel nyní vytvoří soubor index.js
v adresáři public/js
. Stejně jako u našeho souboru leftPad.js
byste měli vidět, že Babel nahradil veškerou syntaxi ES6 a ponechal pouze syntaxi ES5. Můžete si také všimnout, že převedl syntaxi modulu ES6 na syntaxi založenou na uzlu module.exports
, což znamená, že jej můžeme spustit z příkazového řádku:
node public/js/index.js//
Váš terminál by nyní měl vypsat pole řetězců s předponou nula, aby byly všechny osmiznakové. Když máme hotovo, je čas podívat se na webpack.
Představení webpacku a jeho integrace s Babel
Jak již bylo zmíněno, moduly ES6 umožňují vývojáři JavaScriptu rozdělit svůj kód na zvládnutelné kousky, ale důsledkem toho je, že tyto kousky musí být servírovány žádajícímu prohlížeči, což potenciálně přidává desítky dalších požadavků HTTP zpět na server – čemuž bychom se opravdu měli snažit vyhnout. Zde přichází na řadu webpack.
webpack je modul bundler. Jeho hlavním účelem je zpracovat vaši aplikaci tak, že dohledá všechny její závislosti a pak je všechny zabalí do jednoho nebo více balíčků, které lze spustit v prohlížeči. Může však být mnohem víc než to, záleží na tom, jak je nakonfigurován.
Konfigurace balíčkuwebpack je založena na čtyřech klíčových součástech:
- vstupní bod
- výstupní umístění
- zakladače
- zásuvné moduly
Vstupní bod: Zde se nachází počáteční bod vaší aplikace, odkud může webpack identifikovat její závislosti.
Výstupní místo: Zde je uvedeno, kam má být uložen zpracovaný balíček.
Loaders: Zde je uvedeno, kam má být uložen zpracovaný balíček: Jedná se o způsob, jak převést jednu věc jako vstup a vygenerovat něco jiného jako výstup. Lze je použít k rozšíření schopností WebPacku tak, aby zpracovával více než jen soubory JavaScriptu, a proto je také převádí na platné moduly.
Pluginy:
Chcete-li nainstalovat webpack, spusťte z adresáře <ROOT>
následující příkaz:
npm install webpack webpack-cli --save-dev
Tento příkaz nainstaluje webpack lokálně do projektu a také poskytne možnost spustit webpack z příkazového řádku přidáním příkazu webpack-cli
. Nyní byste měli vidět webpack uvedený v souboru package.json
. Zatímco jste v tomto souboru, upravte sekci skriptů následujícím způsobem, aby nyní věděla, že má používat webpack místo přímo Babel:
"scripts": { "build": "webpack --config webpack.config.js"},
Jak vidíte, tento skript volá soubor webpack.config.js
, takže jej vytvořme v našem adresáři <ROOT>
s následujícím obsahem:
To je víceméně nejjednodušší konfigurační soubor, který s webpackem potřebujete. Vidíte, že používá dříve popsané vstupní a výstupní části (mohl by fungovat jen s nimi), ale obsahuje také nastavení mode: 'development'
.
webpack má možnost používat buď režim „development“, nebo „production“. Nastavení mode: 'development'
optimalizuje rychlost sestavení a ladění, zatímco mode: 'production'
optimalizuje rychlost provádění za běhu a velikost výstupního souboru. Dobré vysvětlení režimů najdete v článku Tobiase Kopperse „Webpack 4: režim a optimalizace“, pokud si chcete přečíst více o tom, jak je lze konfigurovat nad rámec výchozího nastavení.
Pak odstraňte všechny soubory ze složky public/js
. Poté znovu spusťte tento příkaz:
npm run build
Uvidíte, že nyní obsahuje jediný soubor ./public/bundle.js
. Po otevření nového souboru však oba soubory, se kterými jsme začínali, vypadají poněkud jinak. Toto je část souboru, která obsahuje kód index.js
. Přestože je oproti našemu originálu poměrně značně upravený, stále můžete rozeznat jeho názvy proměnných:
Pokud spustíte node public/js/bundle.js
ze složky <ROOT>
, uvidíte, že dostanete stejné výsledky jako předtím.
Transpilace
Jak jsme již zmínili, zavaděče nám umožňují převést jednu věc na něco jiného. V tomto případě chceme ES6 převést na ES5. K tomu budeme potřebovat několik dalších balíčků:
npm install babel-loader babel-core --save-dev
Pro jejich využití potřebuje webpack.config.js
za výstupní sekci přidat sekci modulu, například takto:
Pomocí příkazu regex identifikujeme soubory JavaScriptu, které mají být transpilovány pomocí babel-loader
, a zároveň z toho vyloučíme vše, co je ve složce node_modules
. Nakonec se babel-loader
řekne, aby použil dříve nainstalovaný balíček babel-preset-env
pro stanovení parametrů transpile nastavených v souboru .babelrc
.
Po dokončení můžete znovu spustit toto:
npm run build
Poté zkontrolujte nový public/js/bundle.js
a uvidíte, že všechny stopy po syntaxi ES6 zmizely, ale stále to vytváří stejný výstup jako dříve.
Přenesení do prohlížeče
Po vytvoření funkčního nastavení WebPacku a Babelu je čas přenést to, co jsme udělali, do prohlížeče. Je zapotřebí malý soubor HTML, který by měl být vytvořen ve složce <ROOT>
, jak je uvedeno níže:
Pro zobrazení seznamu je zapotřebí ještě trochu JavaScriptu, takže pozměníme ./src/js/index.js
, aby se tak stalo:
Pokud nyní otevřete index.html
v prohlížeči, měl by se zobrazit seřazený seznam takto:
Dále
Podle výše uvedené konfigurace je náš systém sestavování v podstatě připraven k použití. Nyní můžeme pomocí WebPacku svazovat naše moduly a transpilovat kód ES6 dolů na ES5 pomocí Babelu.
Je však trochu nepříjemné, že pro transpilování našeho kódu ES6 musíme při každé změně spustit npm run build
.
Přidání ‚watch‘
Chcete-li překonat nutnost opakovaného spouštění npm run build
, můžete u svých souborů nastavit 'watch'
a nechat webpack automaticky překompilovat pokaždé, když uvidí změnu v některém ze souborů ve složce ./src
. Chcete-li to realizovat, upravte část scripts
souboru package.json
, jak je uvedeno níže:
"scripts": { "watch": "webpack --watch", "build": "webpack --config webpack.config.js"},
Chcete-li zkontrolovat, zda to funguje, spusťte npm run watch
z terminálu a uvidíte, že se již nevrací na příkazový řádek. Nyní se vraťte na src/js/index.js
a do pole serNos
přidejte další hodnotu a uložte ji. Můj nyní vypadá takto:
const serNos = ;
Pokud nyní zkontrolujete terminál, uvidíte, že se odhlásil a že znovu spustil úlohu webpack build
. A po návratu do prohlížeče a obnovení uvidíte, že na konec seznamu byla přidána nová hodnota, která byla zpracována pomocí leftPad
.
Automatické obnovení prohlížeče
Bylo by opravdu dobré, kdyby se nám podařilo přimět Webpack, aby automaticky obnovil prohlížeč při každé změně. Uděláme to tak, že nainstalujeme další balíček npm s názvem webpack-dev-server
. Nezapomeňte však nejprve z úlohy watch
vypsat Ctrl + c!“
npm install webpack-dev-server --save-dev
Po dokončení přidáme do souboru package.json
nový skript, který bude nový balíček volat. Sekce scripts
by nyní měla obsahovat toto:
Všimněte si příznaku --open-page
přidaného na konec skriptu. Ten říká webpack-dev-server
, aby otevřel konkrétní stránku ve vašem výchozím prohlížeči pomocí jeho režimu iframe.
Nyní spusťte npm start
a měli byste vidět, že se otevře nová karta prohlížeče se zobrazeným seznamem dílů. Chcete-li ukázat, že
'watch'
funguje, přejděte na src/js/index.js
a přidejte na konec pole serNos
další novou hodnotu. Po uložení změn byste si měli všimnout, že se v prohlížeči projevily téměř okamžitě.
Po dokončení zbývá pouze nastavit režim v webpack.config.js
na production
. Jakmile to bude nastaveno, bude webpack také minifikovat kód, který vypíše do ./public/js/bundle.js
. Měli byste si uvědomit, že pokud není nastaven mode
, bude webpack ve výchozím nastavení používat konfiguraci production
.
Závěr
V tomto článku jste viděli, jak nastavit systém sestavení pro moderní JavaScript. Zpočátku se k tomu používal Babel z příkazového řádku pro převod syntaxe ES6 na ES5. Poté jste viděli, jak využít moduly ES6 pomocí klíčových slov export
a import
, jak integrovat webpack k provedení úlohy svazování a jak přidat úlohu sledování k automatickému spuštění webpaku při každé detekci změn zdrojového souboru. Nakonec jste viděli, jak nainstalovat webpack-dev-server
pro automatické obnovení stránky při každé změně.
Pokud byste chtěli pokračovat dál, doporučuji přečíst si SitePointův hluboký ponor do webpaku a svazování modulů a také prozkoumat další zavaděče a zásuvné moduly, které umožní webpaku zpracovávat úlohy Sass a komprese aktiv. Podívejte se také na eslint-loader
a zásuvný modul pro Prettier too.
Happy bundling …
.