保持控制(Webpack和React指南(2))

本文概述

  • 使用Webpack进行TypeScript和React:输入Babel
  • CSS, 通过Webpack增强
  • 网络工作者
  • 服务人员
  • Advanced React Webpack Config:使你的项目更具优势
在本React-Webpack教程的第一部分中, 我们讨论了如何配置加载器和执行优化。现在, 我们将研究与特定React / Webpack配置用例相关的更高级的技术。
使用Webpack进行TypeScript和React:输入Babel在React项目中可以使用几种方式使用TypeScript。虽然ts-loader是一个不错的选择, 但我想重点介绍如何使用@ babel / preset-typescript转换TypeScript, 因为许多库都在发布Babel插件来执行编译时间优化。除了处理TypeScript文件之外, 它还使我们能够使用各种库(例如, 样式组件或react-intl)提供的Babel插件。
我们需要做的第一件事是安装TypeScript和Babel依赖项:
npm install -D typescript @babel/preset-typescript @types/react @types/react-dom

然后, 我们将使用命令行程序tsc生成TypeScript配置文件:
./node_modules/.bin/tsc -init --lib dom --jsx react --isolatedModules

上面的命令将生成一个tsconfig.json, 适用于为浏览器环境编写代码。 – isolatedModules选项强制执行一些约束, 以确保你编写的代码与@ babel / plugin-transform-typescript兼容。此选项很有用, 以便在你以无法转换的方式编写代码时使你的IDE发出警告。
接下来, 我们将通过引入新的预设来更新babel.config.js:
@@ -6, 7 +6, 8 @@ module.exports = { modules: false } ], -"@babel/preset-react" +"@babel/preset-react", +"@babel/preset-typescript" ], plugins: [ "@babel/plugin-transform-runtime",

并在webpack.config.js中启用.ts文件扩展名:
@@ -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({

上面的配置足以转换我们的代码, 但实际上并没有对其进行验证。我们将需要使用fork-ts-checker-webpack-plugin在一个单独的并行过程中执行类型检查。
首先, 我们需要安装它:
npm install -D fork-ts-checker-webpack-plugin

然后, 将其添加到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: {

指定async:false将防止Webpack发出无效代码并在运行开发服务器时在覆盖中显示编译错误。
注意:你可能还对Babel宏感兴趣, 这些宏越来越受欢迎。
CSS, 通过Webpack增强在上一篇文章中, 我们介绍了使用css-loader的基本样式。我们可以通过几种方法来改进此配置。
提议的配置将利用CSS模块, Sass和PostCSS技术。尽管它们确实可以在某些方面相互补充, 但是你无需同时使用所有它们。最终设置将启用上述所有插件, 如果你确定” 你将不需要它” , 我们将由你决定是否将其遗漏。
CSS模块
CSS模块通过为每个CSS类生成一个随机的唯一名称来解决CSS文件中全局作用域的问题。从使用CSS模块的JavaScript文件的角度来看, 原始类名与随机类名之间的关联由加载程序导出的对象表示。它使你能够以几乎不可能发生意外冲突的方式查找和使用CSS文件中指定的类。
CSS模块支持已包含在css-loader中。现在, 我们需要添加一个新规则, 以明确说明何时使用CSS模块:
@@ -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: {

这样, 任何以.module.css结尾的文件都将在启用CSS模块的情况下进行处理。
后CSS
PostCSS是具有大量插件库的可扩展CSS处理框架, 可用于扩展CSS语法, 执行优化或为较旧的浏览器提供后备功能。
首先, 我们将安装必要的依赖项:
npm install -D postcss-loader postcss-import postcss-preset-env

并更新我们的CSS配置:
@@ -47, 9 +47, 11 @@ module.exports = function(_env, argv) { { loader: "css-loader", options: { -modules: true +modules: true, +importLoaders: 1 } -} +}, +"postcss-loader" ] }, {

我们将使用以下插件配置PostCSS:
  • postcss-import:使PostCSS能够处理@import语句
  • postcss-preset-env:应用polyfill在大多数浏览器中支持现代CSS功能
创建一个名为postcss.config.js的文件, 并使用以下内容进行填充:
module.exports = { plugins: { "postcss-import": {}, "postcss-preset-env": {} } };

你可以检出PostCSS插件目录中可能有用的其他扩展, 并将其添加到配置中。
Sass / SCSS
Sass是另一个流行的CSS处理框架。与PostCSS不同, Sass带有” 包括电池” 。开箱即用, Sass提供对嵌套规则, mixin和重写规则的支持, 以实现向后兼容。尽管PostCSS旨在保留标准CSS语法, 但Sass语法可能与CSS规范有所不同。尽管如此, Sass是一种无处不在的解决方案, 使用它来编写CSS可能只是一个更简单的选择-但是这取决于你的要求。
首先, 我们将安装必要的依赖项:
npm install -D sass-loader node-sass resolve-url-loader

然后, 将新的加载器添加到我们的Webpack配置中:
@@ -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: {

我们使用上述摘要抢先解决了几个问题:
  1. 我们在sass-loader之后引入了resolve-url-loader, 以使@imported Sass文件中的相对导入工作。
  2. 我们为css-loader指定了importLoaders选项, 以便使用其后的加载器来处理@ import-ed文件。
通过上述配置, 除了我们之前描述的PostCSS和CSS模块之外, 我们还可以开始使用Sass / SCSS创作样式。尽管可以同时启用所有这些选项, 但是你不必在同一项目中全部使用它们, 因此你可以选择最适合自己需求的一种工具。
网络工作者网络工作者是现代网络的强大概念。它使你可以从主线程分流昂贵的计算。应谨慎使用网络工作者, 并将其保留给事件循环中无法通过智能计划进行优化的工作。使用Web Worker是优化长时间同步操作的理想选择。
Webpack使使用worker-loader的web worker变得容易使用, 它可以将worker文件捆绑到输出目录中, 并为使用者文件提供worker类。
首先, 我们需要安装worker-loader:
npm install -D worker-loader

然后将其添加到我们的配置文件中:
@@ -31, 6 +31, 10 @@ module.exports = function(_env, argv) { } } }, +{ +test: /\.worker\.js$/, +loader: "worker-loader" +}, { test: /\.css$/, use: [

现在, 开始使用Web Worker所需要做的就是实例化一个以.worker.js结尾的文件导入的类, 该文件实现了普通的Worker API。
服务人员服务人员启用高级优化技术并改善用户体验。当用户失去网络连接时, 它们可使你的应用程序脱机工作。他们甚至可以在推送更新后立即加载你的应用。
Webpack使你可以使用workbox-webpack-plugin模块轻松为你的应用配置服务工作者。首先, 我们需要安装它:
npm install -D workbox-webpack-plugin

然后, 将插件添加到Webpack配置的插件部分:
@@ -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: {

上面的配置使用以下选项:
  • swDest指定生成的辅助文件的输出文件名。
  • clientsClaim指示服务工作者在注册后立即控制页面, 并开始提供缓存的资源, 而不是等待下一页的重新加载。
  • skipWaiting使对服务工作者的更新立即生效, 而不必等待所有活动实例被销毁。
有一个很好的理由说明后两个选项不是默认选项。如果同时启用该功能, 则在时间敏感的情况下可能会发生故障, 因此, 你需要做出明智的决定, 以决定是否在配置中保持启用这些选项。
最后, 当用户打开我们的应用程序时, 我们需要注册服务工作者:
@@ -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"); +}); +}

服务工作者的功能远远不止于为我们的应用程序添加脱机功能。如果你需要更好地控制服务工作者的行为, 则可以改用InjectManifest插件。通过编写自己的服务工作者文件, 你还可以为API请求启用缓存, 并使用服务工作者启用的其他功能, 例如推送通知。你可以在其官方文档的” 高级食谱” 部分中找到有关Workbox功能的更多信息。
Advanced React Webpack Config:使你的项目更具优势Webpack教程系列的第二部分应该为你提供了必要的知识, 可以将你的Webpack配置扩展到最一般的React用例之外。我希望你发现此信息有用, 并且你可以放心地扩展个性化配置, 以实现特定于项目的目标。
【保持控制(Webpack和React指南(2))】与往常一样, 你可以在GitHub上找到完整的配置文件, 并参考Webpack文档及其插件部分以找到适用于你目标的更多食谱。感谢你的阅读!

    推荐阅读