本文概述
- 使用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: {
我们使用上述摘要抢先解决了几个问题:
-
我们在sass-loader之后引入了resolve-url-loader, 以使@imported Sass文件中的相对导入工作。
-
我们为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文档及其插件部分以找到适用于你目标的更多食谱。感谢你的阅读!