作者都是各自领域经过审查的专家,并撰写他们有经验的主题. 我们所有的内容都经过同行评审,并由同一领域的Toptal专家验证.
迈克尔·本都的头像

迈克尔·蓬托斯

Michael是一名高级全栈开发人员,专门从事React和TypeScript的前端开发.

工作经验

7

Share

In 这是React-Webpack教程的第一部分,我们讨论了如何配置加载器和执行优化. 现在,我们将进入与特定React/Webpack配置用例相关的更高级的技术.

TypeScript和React with Webpack:进入Babel

中使用TypeScript有几种方法 React project. While ts-loader 是一个很好的选择,我想专注于如何使用 @babel / preset-typescript 因为许多库都发布了Babel插件来执行编译时优化. 除了处理TypeScript文件之外, 它将允许我们使用各种库提供的Babel插件,例如 styled-components or react-intl.

我们需要做的第一件事是安装TypeScript和Babel依赖项:

npm install -D typescript @babel/预设typescript @types/react @types/react-dom

然后,我们将使用命令行程序生成一个TypeScript配置文件 tsc:

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

上面的命令将生成一个 tsconfig.json 适合为浏览器环境编写代码. The ——isolatedModules 选项强制执行一些约束,以确保您编写的代码将与 @babel / plugin-transform-typescript. 当您以Babel无法转换的方式编写代码时,IDE会警告您,此选项非常有用.

接下来,我们要进行更新 babel.config.js 通过引入一个新的预设:

@@ -6,7 +6,8 @@模块.exports = {
         模块:假
       }
     ],
——“@babel / preset-react”
+“@babel / preset-react”,
+“@babel / preset-typescript”
   ],
   plugins: [
     “@babel / plugin-transform-runtime”,

然后启用 .ts 文件扩展名为 webpack.config.js:

@@ -11,7 +11,7 @@模块.Exports = function(_env, argv) {

   return {
     devtool: isDevelopment && “cheap-module-source-map”,
-入口:"./src/index.js",
+ entry: "./src/index.tsx",
     output: {
       path: path.解决(__dirname " dist”),
       文件名:“资产/ js /[名称].(contenthash: 8).js",
@@ -20,7 +20,7 @@模块.Exports = function(_env, argv) {
     module: {
       rules: [
         {
- test: /\.jsx?$/,
+ test: /\.(js | jsx | ts | tsx) /美元,
           排除:/ node_modules /,
           use: {
             装载机:“babel-loader”,
@@ -61,6 +61,9 @@模块.Exports = function(_env, argv) {
         }
       ]
     },
+ resolve: {
+ extensions: [".js", ".jsx", ".ts", ".tsx"]
+    },
     plugins: [
       isProduction &&
         新MiniCssExtractPlugin ({

上面的配置足以翻译我们的代码,但它实际上并没有验证它. 我们将需要在一个单独的并行进程中执行类型检查,使用 fork-ts-checker-webpack-plugin.

首先,我们需要安装它:

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

然后,我们把它加到 plugins section in webpack.config.js:

@@ -4,6 +4,7 @@ const HtmlWebpackPlugin = require("html-webpack-plugin");
 Const webpack = require("webpack");
 const TerserWebpackPlugin = require(" terserwebpack -plugin");
 const optimizecssassetplugin = require("optimize-css-assets-webpack-plugin");
+const ForkTsCheckerWebpackPlugin = require("fork-ts-checker-webpack-plugin");

 module.Exports = function(_env, argv) {
   const isProduction = argv.模式===“生产”;
@@ -78,6 +79,9 @@模块.Exports = function(_env, argv) {
         "process.env.NODE_ENV”:JSON.stringify(
           isProduction ? “生产”:“发展”
         )
+      }),
+ new ForkTsCheckerWebpackPlugin({
+ async: false
       })
     ].过滤器(布尔),
     优化:{

Specifying async: false 当运行开发服务器时,将阻止Webpack发出无效代码并在覆盖中显示编译错误.

注:您也可能对 Babel macros这些项目正获得越来越多的关注.

CSS,通过Webpack增强

在上一篇文章中,我们介绍了使用的基本样式 css-loader. 有几种方法可以改进这种配置.

建议的配置将利用 CSS Modules, Sass, and PostCSS technologies. 尽管它们在某些方面是互补的, 你不需要同时使用它们. 最后的设置将启用上述所有插件, 如果你确定“你不需要它”,我们会把它留给你.”

CSS Modules

CSS Modules 通过生成一个随机的, 每个CSS类的唯一名称. 从使用CSS模块的JavaScript文件的角度来看, 原始类名和随机化类名之间的关联由加载器导出的对象表示. 它允许您以一种几乎不可能发生意外冲突的方式查找和使用CSS文件中指定的类.

CSS模块支持已经包含在 css-loader. 现在我们需要添加一条新规则,明确CSS模块何时被使用:

@@ -33,11 +33,25 @@模块.Exports = function(_env, argv) {
         },
         {
           test: /\.css$/,
           use: [
             isProduction ? MiniCssExtractPlugin.Loader:“style-loader”;
             "css-loader"
           ]
         },
+        {
+ test: /\.module.css$/,
+使用:[
+            isProduction ? MiniCssExtractPlugin.Loader:“style-loader”;
+            {
+ loader:“css-loader”;
+ options: {
+ modules: true
+              }
+            }
+          ]
+        },
         {
           test: /\.(png | jpg | gif) $ /我,
           use: {

这样,任何文件的结尾都是 .module.css 将在启用CSS模块的情况下进行处理.

PostCSS

PostCSS是一个可扩展的CSS处理框架,有一个巨大的插件库,你可以用它来扩展CSS语法, 执行优化, 或者为旧的浏览器提供回退.

首先,我们要安装必要的依赖项:

postcss-import postcss-preset-env

更新我们的CSS配置:

@@ -47,9 +47,11 @@模块.Exports = function(_env, argv) {
             {
               装载机:“css-loader”,
               options: {
- modules: true
+ modules: true,
+ importloader: 1
               }
-            }
+            },
+            " postcss-loader”
           ]
         },
         {

我们将使用以下插件来配置PostCSS:

  • postcss-import:启用PostCSS处理 @import statements
  • postcss-preset-env:在大多数浏览器中应用多边形来支持现代CSS特性

创建一个文件 postcss.config.js 然后用下面的代码填充它:

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

你可以退房 PostCSS插件目录 对于其他可能有用的扩展,请将它们添加到配置中.

Sass/SCSS

Sass 另一个流行的CSS处理框架是什么. 与PostCSS不同,Sass自带“电池”.“从盒子里拿出来, Sass提供对嵌套规则的支持, mixins, 重写向后兼容的规则. 虽然PostCSS旨在保留标准的CSS语法,但Sass语法可能会偏离CSS规范. Despite this, Sass是一种无处不在的解决方案,使用它来编写CSS可能是一种更简单的选择——但这是一种错误的选择 这取决于你的要求.

首先,我们要安装必要的依赖项:

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

然后,在我们的Webpack配置中添加一个新的加载器:

@@ -38,6 +38,25 @@模块.Exports = function(_env, argv) {
             "css-loader"
           ]
         },
+        {
+ test: /\.s[ac]ss$/,
+使用:[
+            isProduction ? MiniCssExtractPlugin.Loader:“style-loader”;
+            {
+ loader:“css-loader”;
+ options: {
+ importloader: 2
+              }
+            },
+            " resolve-url-loader”,
+            {
+ loader: "sass-loader",
+ options: {
+ sourceMap: true
+              }
+            }
+          ]
+        },
         {
           test: /\.(png | jpg | gif) $ /我,
           use: {

我们先发制人地用上面的代码片段解决了几个问题:

  1. 我们介绍了 resolve-url-loader after sass-loader 使相对进口起作用 @imported Sass文件.

  2. We specified importLoaders option for css-loader to process @import使用它后面的加载器加载-ed文件.

使用上述配置, 除了我们之前描述过的PostCSS和CSS模块,我们还可以开始使用Sass/SCSS来创建样式. 尽管所有这些选项都可以同时启用, 您不必在同一个项目中全部使用它们, 因此,您可以选择最适合您需求的工具.

Web Workers

Web workers 是现代网络的一个强大概念吗. 它使您可以从主线程中卸载昂贵的计算. 应该谨慎地使用Web worker,并将其保留给无法通过事件循环中的智能调度进行优化的事情. 使用web worker是优化长时间同步操作的一个很好的选择.

Webpack使web工作者更容易使用 worker-loader, 哪个将worker文件捆绑到输出目录中,并为消费者文件提供worker类.

首先,我们需要安装 worker-loader:

npm install -D worker-loader

然后将它添加到我们的配置文件中:

@@ -31,6 +31,10 @@模块.Exports = function(_env, argv) {
             }
           }
         },
+        {
+ test: /\.worker\.js$/,
+ loader:“worker-loader”
+        },
         {
           test: /\.css$/,
           use: [

Now, 要开始使用web worker,你所需要做的就是实例化一个从以。结尾的文件导入的类 .worker.js 它实现了普通的 Worker API.

服务工作人员

Service worker支持先进的优化技术和用户体验的改进. 当用户失去网络连接时,它们可以让你的应用离线工作. 它们还能让你的应用在更新后立即加载.

Webpack可以很容易地为应用配置service worker workbox-webpack-plugin module. 首先,我们需要安装它:

npm install -D workbox-webpack-plugin

然后,我们将插件添加到 plugins 部分的Webpack配置:

@@ -4,6 +4,7 @@ const HtmlWebpackPlugin = require("html-webpack-plugin");
 Const webpack = require("webpack");
 const TerserWebpackPlugin = require(" terserwebpack -plugin");
 const optimizecssassetplugin = require("optimize-css-assets-webpack-plugin");
+const WorkboxPlugin = require("workbox-webpack-plugin");

 module.Exports = function(_env, argv) {
   const isProduction = argv.模式===“生产”;
@@ -75,6 +76,11 @@模块.Exports = function(_env, argv) {
         "process.env.NODE_ENV”:JSON.stringify(
           isProduction ? “生产”:“发展”
         )
+      }),
+新的WorkboxPlugin.GenerateSW({
+ swDest:“service-worker.js",
+ clientsClaim: true,
+ skipWaiting: true
       })
     ].过滤器(布尔),
     优化:{

上述配置使用以下选项:

  • swDest 指定生成的工作文件的输出文件名.
  • clientsClaim 指示service worker在注册后立即控制页面,并开始提供缓存的资源,而不是等待下一个页面重新加载.
  • skipWaiting 使对service worker的更新立即生效,而不是等待所有活动实例被销毁.

后两个选项不是默认选项有很好的理由. 当同时启用时,有可能 在时间敏感的情况下发生故障, 因此,是否在配置中启用这些选项取决于您是否有意识地做出决定.

最后,我们需要在用户打开应用时注册service worker:

@@ -2,3 +2,9 @@从“React”中导入React;
 从“react-dom”中导入ReactDOM;

 ReactDOM.render(

React App

, document.getElementById("根")); + +if ("serviceWorker" in navigator) { + window.addEventListener("load", () => { +导航器.serviceWorker.注册(“/管理局的职员.js"); + }); +}

Service worker的功能远不止为我们的应用添加离线功能. 如果你需要对service worker的行为进行更大程度的控制,那么你可以使用 InjectManifest 插件而不是. 通过编写自己的service worker文件, 你还可以为API请求启用缓存,并使用service worker启用的其他功能,比如推送通知. 中找到有关Workbox功能的更多信息 高级食谱部分的官方文档.

高级React Webpack配置:给你的项目一个优势

我们Webpack教程系列的第二部分应该已经为您提供了必要的知识,以扩展您的Webpack配置,使其超越最通用的React用例. 我希望您发现这些信息有用,并且您可以自信地扩展您的个性化配置以实现特定于您的项目的目标.

一如既往,你可以找到 GitHub上的完整配置文件 并参考 Webpack文档 and 它的插件部分 找到更多适合你目标的食谱. 谢谢你的阅读!

了解基本知识

  • babel-loader包做什么?

    Babel-loader允许使用Babel及其各种插件处理导入的JavaScript文件.

  • 什么是Webpack加载器?

    在Webpack中,加载器指定处理导入文件的规则.

  • 谁创建了Webpack?

    Webpack项目由Tobias Koppers于2012年3月创建,至今仍有许多Webpack维护者和贡献者在继续开发.

  • Webpack配置是什么?

    Webpack config是一个JavaScript对象,它指定了处理输入文件和创建输出包的规则.

  • 为什么要使用Webpack?

    Webpack用于将现代JavaScript代码转换成可以在浏览器中执行的bundle.

聘请Toptal这方面的专家.
Hire Now
迈克尔·本都的头像
迈克尔·蓬托斯

Located in 圣彼得堡,俄罗斯

Member since 2018年12月5日

作者简介

Michael是一名高级全栈开发人员,专门从事React和TypeScript的前端开发.

Toptal作者都是各自领域经过审查的专家,并撰写他们有经验的主题. 我们所有的内容都经过同行评审,并由同一领域的Toptal专家验证.

工作经验

7

世界级的文章,每周发一次.

订阅意味着同意我们的 隐私政策

世界级的文章,每周发一次.

订阅意味着同意我们的 隐私政策

Toptal开发者

加入总冠军® community.