Utrzymuj kontrolę: przewodnik po pakietach internetowych i reagowaniu, cz. 2

Opublikowany: 2022-03-11

W pierwszej części tego samouczka React-Webpack omówiliśmy, jak skonfigurować programy ładujące i przeprowadzić optymalizację. Teraz zajmiemy się bardziej zaawansowanymi technikami związanymi z konkretnymi przypadkami użycia konfiguracji React/Webpack.

TypeScript i React z Webpack: Wprowadź Babel

Istnieje kilka sposobów wykorzystania TypeScriptu w projekcie React. Chociaż ts-loader jest dobrą opcją, chciałbym skupić się na tym, jak transpilować TypeScript za pomocą @babel/preset-typescript ponieważ wiele bibliotek publikuje wtyczki Babel do optymalizacji czasu kompilacji. Poza przetwarzaniem plików TypeScript, pozwoli nam to na korzystanie z wtyczek Babel dostarczanych przez różne biblioteki, takie jak styled-components czy reakcja-intl.

Pierwszą rzeczą, którą musimy zrobić, to zainstalować zależności TypeScript i Babel:

 npm install -D typescript @babel/preset-typescript @types/react @types/react-dom

Następnie wygenerujemy plik konfiguracyjny TypeScript za pomocą programu wiersza poleceń tsc :

 ./node_modules/.bin/tsc -init --lib dom --jsx react --isolatedModules

Powyższe polecenie wygeneruje plik tsconfig.json odpowiedni do pisania kodu dla środowiska przeglądarki. Opcja --isolatedModules wymusza pewne ograniczenia, które zapewniają, że napisany kod będzie zgodny z @babel/plugin-transform-typescript . Ta opcja jest przydatna, aby Twoje IDE ostrzegało Cię, gdy piszesz kod w sposób, którego Babel nie będzie w stanie przekształcić.

Następnie zaktualizujemy babel.config.js , wprowadzając nowe ustawienie wstępne:

 @@ -6,7 +6,8 @@ module.exports = { modules: false } ], - "@babel/preset-react" + "@babel/preset-react", + "@babel/preset-typescript" ], plugins: [ "@babel/plugin-transform-runtime",

I włącz rozszerzenie pliku .ts w webpack.config.js :

 @@ -11,7 +11,7 @@ module.exports = function(_env, argv) { return { devtool: isDevelopment && "cheap-module-source-map", - entry: "./src/index.js", + entry: "./src/index.tsx", output: { path: path.resolve(__dirname, "dist"), filename: "assets/js/[name].[contenthash:8].js", @@ -20,7 +20,7 @@ module.exports = function(_env, argv) { module: { rules: [ { - test: /\.jsx?$/, + test: /\.(js|jsx|ts|tsx)$/, exclude: /node_modules/, use: { loader: "babel-loader", @@ -61,6 +61,9 @@ module.exports = function(_env, argv) { } ] }, + resolve: { + extensions: [".js", ".jsx", ".ts", ".tsx"] + }, plugins: [ isProduction && new MiniCssExtractPlugin({

Powyższa konfiguracja jest wystarczająca, aby móc transpilować nasz kod, ale w rzeczywistości go nie waliduje. Będziemy musieli przeprowadzić sprawdzanie typu w oddzielnym, równoległym procesie za pomocą fork-ts-checker-webpack-plugin .

Najpierw musimy go zainstalować:

 npm install -D fork-ts-checker-webpack-plugin

Następnie dodamy go do sekcji plugins w webpack.config.js :

 @@ -4,6 +4,7 @@ const HtmlWebpackPlugin = require("html-webpack-plugin"); const webpack = require("webpack"); const TerserWebpackPlugin = require("terser-webpack-plugin"); const OptimizeCssAssetsPlugin = require("optimize-css-assets-webpack-plugin"); +const ForkTsCheckerWebpackPlugin = require("fork-ts-checker-webpack-plugin"); module.exports = function(_env, argv) { const isProduction = argv.mode === "production"; @@ -78,6 +79,9 @@ module.exports = function(_env, argv) { "process.env.NODE_ENV": JSON.stringify( isProduction ? "production" : "development" ) + }), + new ForkTsCheckerWebpackPlugin({ + async: false }) ].filter(Boolean), optimization: {

Określenie async: false uniemożliwi wyemitowanie przez pakiet Webpack nieprawidłowego kodu i wyświetlenie błędów kompilacji w nakładce podczas uruchamiania serwera programistycznego.

Uwaga: Możesz również zainteresować się makrami Babel, które zyskują na popularności.

CSS, ulepszony przez Webpack

W poprzednim artykule omówiliśmy podstawową stylizację za pomocą css-loader . Istnieje kilka sposobów na ulepszenie tej konfiguracji.

Proponowana konfiguracja będzie korzystała z modułów CSS, Sass i technologii PostCSS. Chociaż w pewien sposób się uzupełniają, nie musisz używać ich wszystkich jednocześnie. Ostateczna konfiguracja będzie miała włączone wszystkie powyższe wtyczki, a pozostawimy tobie pozostawienie czegoś, jeśli masz pewność, że „nie będziesz tego potrzebować”.

Moduły CSS

Moduły CSS rozwiązują problem globalnego określania zakresu w plikach CSS, generując losową, unikatową nazwę dla każdej klasy CSS. Z punktu widzenia pliku JavaScript zużywającego moduł CSS, powiązanie pomiędzy oryginalną nazwą klasy a tą zrandomizowaną jest reprezentowane przez obiekt wyeksportowany przez loader. Pozwala znaleźć i używać klas określonych w pliku CSS w sposób, który sprawia, że ​​przypadkowa kolizja jest prawie niemożliwa.

Obsługa modułów CSS jest już zawarta w css-loader . Teraz będziemy musieli dodać nową regułę, aby jasno określić, kiedy moduły CSS są używane:

 @@ -33,11 +33,25 @@ module.exports = function(_env, argv) { }, { test: /\.css$/, use: [ isProduction ? MiniCssExtractPlugin.loader : "style-loader", "css-loader" ] }, + { + test: /\.module.css$/, + use: [ + isProduction ? MiniCssExtractPlugin.loader : "style-loader", + { + loader: "css-loader", + options: { + modules: true + } + } + ] + }, { test: /\.(png|jpg|gif)$/i, use: {

Dzięki temu każdy plik kończący się na .module.css zostanie przetworzony z włączonymi modułami CSS.

PostCSS

PostCSS to rozszerzalna struktura przetwarzania CSS z ogromną biblioteką wtyczek, których możesz użyć do rozszerzenia składni CSS, przeprowadzenia optymalizacji lub zapewnienia rozwiązań awaryjnych dla starszych przeglądarek.

Najpierw zainstalujemy niezbędne zależności:

 npm install -D postcss-loader postcss-import postcss-preset-env

I zaktualizuj naszą konfigurację CSS:

 @@ -47,9 +47,11 @@ module.exports = function(_env, argv) { { loader: "css-loader", options: { - modules: true + modules: true, + importLoaders: 1 } - } + }, + "postcss-loader" ] }, {

Skonfigurujemy PostCSS za pomocą następujących wtyczek:

  • postcss-import : Umożliwia PostCSS przetwarzanie wyciągów @import
  • postcss-preset-env : Stosuje wypełnienie do obsługi nowoczesnych funkcji CSS w większości przeglądarek

Utwórz plik o nazwie postcss.config.js i wypełnij go następującymi danymi:

 module.exports = { plugins: { "postcss-import": {}, "postcss-preset-env": {} } };

Możesz sprawdzić katalog wtyczek PostCSS, aby znaleźć inne rozszerzenia, które mogą Ci się przydać, i dodać je do swojej konfiguracji.

Sass/SCSS

Sass to kolejna popularna platforma przetwarzania CSS. W przeciwieństwie do PostCSS, Sass zawiera „baterie w zestawie”. Po wyjęciu z pudełka Sass oferuje obsługę zagnieżdżonych reguł, domieszek i reguł przepisywania w celu zapewnienia kompatybilności wstecznej. Chociaż PostCSS ma na celu zachowanie standardowej składni CSS, składnia Sass może odbiegać od specyfikacji CSS. Mimo to Sass jest tak wszechobecnym rozwiązaniem, że używanie go do tworzenia CSS może być po prostu łatwiejszą opcją — ale taką, która zależy od Twoich wymagań.

Najpierw zainstalujemy niezbędne zależności:

 npm install -D sass-loader node-sass resolve-url-loader

Następnie dodaj nowy loader do naszej konfiguracji Webpacka:

 @@ -38,6 +38,25 @@ module.exports = function(_env, argv) { "css-loader" ] }, + { + test: /\.s[ac]ss$/, + use: [ + isProduction ? MiniCssExtractPlugin.loader : "style-loader", + { + loader: "css-loader", + options: { + importLoaders: 2 + } + }, + "resolve-url-loader", + { + loader: "sass-loader", + options: { + sourceMap: true + } + } + ] + }, { test: /\.(png|jpg|gif)$/i, use: {

Zawczasu rozwiązaliśmy kilka problemów z powyższym fragmentem:

  1. Wprowadziliśmy resolve-url-loader po sass-loader , aby względne importy działały z plików @import ed Sass.

  2. Określiliśmy opcję importLoaders dla css-loader do przetwarzania plików @import -ed za pomocą programów ładujących, które po niej następują.

Dzięki powyższej konfiguracji możemy rozpocząć tworzenie naszych stylów przy użyciu Sass/SCSS oprócz modułów PostCSS i CSS, które opisaliśmy wcześniej. Chociaż wszystkie te opcje można włączyć jednocześnie, nie musisz używać ich wszystkich w tym samym projekcie, więc możesz wybrać jedno narzędzie, które najlepiej odpowiada Twoim wymaganiom.

Pracownicy sieciowi

Pracownicy sieci Web to potężna koncepcja nowoczesnej sieci. Pozwala odciążyć drogie obliczenia z głównego wątku. Narzędzia sieciowe powinny być używane oszczędnie i zarezerwowane dla rzeczy, których nie można w inny sposób zoptymalizować za pomocą inteligentnego planowania w pętli zdarzeń. Korzystanie z pracowników sieci Web jest dobrym kandydatem do optymalizacji długich operacji synchronicznych.

Pakiet Webpack ułatwia korzystanie z procesów roboczych sieci Web za pomocą narzędzia worker-loader , które łączy pliki robocze w katalogu wyjściowym i udostępnia klasę roboczą do pliku konsumenta.

Najpierw musimy zainstalować worker-loader :

 npm install -D worker-loader

Następnie dodaj go do naszego pliku konfiguracyjnego:

 @@ -31,6 +31,10 @@ module.exports = function(_env, argv) { } } }, + { + test: /\.worker\.js$/, + loader: "worker-loader" + }, { test: /\.css$/, use: [

Teraz wszystko, co musisz zrobić, aby zacząć korzystać z procesów roboczych, to utworzyć instancję klasy zaimportowanej z pliku z rozszerzeniem .worker.js , która implementuje zwykły interfejs Worker API.

Pracownicy usług

Pracownicy usług umożliwiają zaawansowane techniki optymalizacji i poprawę doświadczenia użytkownika. Pozwalają aplikacji działać w trybie offline, gdy użytkownik utraci połączenie sieciowe. Pozwalają również na natychmiastowe ładowanie aplikacji, nawet po wypchnięciu aktualizacji.

Webpack ułatwia konfigurowanie Service Workerów dla Twojej aplikacji za pomocą modułu workbox-webpack-plugin. Najpierw musimy go zainstalować:

 npm install -D workbox-webpack-plugin

Następnie dodamy wtyczkę do sekcji plugins w naszej konfiguracji Webpacka:

 @@ -4,6 +4,7 @@ const HtmlWebpackPlugin = require("html-webpack-plugin"); const webpack = require("webpack"); const TerserWebpackPlugin = require("terser-webpack-plugin"); const OptimizeCssAssetsPlugin = require("optimize-css-assets-webpack-plugin"); +const WorkboxPlugin = require("workbox-webpack-plugin"); module.exports = function(_env, argv) { const isProduction = argv.mode === "production"; @@ -75,6 +76,11 @@ module.exports = function(_env, argv) { "process.env.NODE_ENV": JSON.stringify( isProduction ? "production" : "development" ) + }), + new WorkboxPlugin.GenerateSW({ + swDest: "service-worker.js", + clientsClaim: true, + skipWaiting: true }) ].filter(Boolean), optimization: {

Powyższa konfiguracja wykorzystuje następujące opcje:

  • swDest określa nazwę pliku wyjściowego dla wygenerowanego pliku roboczego.
  • clientsClaim instruuje pracownika serwisu, aby przejął kontrolę nad stroną natychmiast po rejestracji i zaczął udostępniać buforowane zasoby zamiast czekać na kolejne przeładowanie strony.
  • skipWaiting sprawia, że ​​aktualizacje Service Workera zaczynają obowiązywać natychmiast, zamiast czekać na zniszczenie wszystkich aktywnych instancji.

Jest dobry powód, dla którego dwie ostatnie opcje nie są domyślne. Gdy są włączone jednocześnie, istnieje ryzyko wystąpienia usterek w sytuacjach, w których czas ma duże znaczenie, więc to do Ciebie należy podjęcie świadomej decyzji, czy pozostawić te opcje włączone w swojej konfiguracji.

Na koniec musimy zarejestrować pracownika serwisu, gdy użytkownik otworzy naszą aplikację:

 @@ -2,3 +2,9 @@ import React from "react"; import ReactDOM from "react-dom"; ReactDOM.render(<h3>React App</h3>, document.getElementById("root")); + +if ("serviceWorker" in navigator) { + window.addEventListener("load", () => { + navigator.serviceWorker.register("/service-worker.js"); + }); +}

Pracownicy usług są w stanie o wiele więcej niż dodawanie funkcji offline do naszej aplikacji. Jeśli potrzebujesz większej kontroli nad zachowaniem Service Worker, możesz zamiast tego użyć wtyczki InjectManifest . Pisząc własny plik Service Worker, możesz także włączyć buforowanie żądań API i korzystać z innych funkcji udostępnianych przez Service Workery, takich jak powiadomienia push. Możesz dowiedzieć się więcej o możliwościach Workboksa w sekcji Zaawansowane przepisy w jego oficjalnej dokumentacji.

Advanced React Webpack Config: nadanie projektowi przewagi

Ta druga część naszej serii samouczków Webpack powinna uzbroić Cię w niezbędną wiedzę, aby rozszerzyć konfigurację Webpack poza najbardziej ogólne przypadki użycia Reacta. Mam nadzieję, że te informacje okazały się przydatne i że możesz śmiało rozszerzyć swoją spersonalizowaną konfigurację, aby osiągnąć cele specyficzne dla Twojego projektu.

Jak zawsze, możesz znaleźć pełne pliki konfiguracyjne na GitHub i zapoznać się z dokumentacją Webpack i sekcją jego wtyczek, aby znaleźć więcej przepisów mających zastosowanie do Twoich celów. Dziękuję za przeczytanie!