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

本文概述

在本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用例之外。我希望你发现此信息有用, 并且你可以放心地扩展个性化配置, 以实现特定于项目的目标。

与往常一样, 你可以在GitHub上找到完整的配置文件, 并参考Webpack文档及其插件部分以找到适用于你目标的更多食谱。感谢你的阅读!

微信公众号
手机浏览(小程序)
0
分享到:
没有账号? 忘记密码?