这里有一篇关于用Webpack捆绑React和TypeScript应用的最新文章。
在这篇文章中,我们将介绍如何使用webpack来捆绑React和TypeScript应用。我们还将包括如何使用webpack在开发应用时提供一个很棒的体验。我们的设置将确保在webpack过程中发生类型检查和提示,这将有助于代码质量。
创建一个基本项目
让我们在我们选择的根文件夹中创建以下文件夹:
build:这是所有构建输出的工件的地方。这里也将存放React应用将被注入的HTML页面。src:这将存放我们的源代码。
注意,当我们开始安装项目的依赖项时,也将创建一个node_modules 文件夹。
在项目的根部,添加以下package.json 文件:
{
"name": "my-app",
"version": "0.0.1"
}
当我们在本篇文章中安装项目的依赖项时,该文件将自动更新。
让我们也把下面的index.html 文件添加到build 文件夹中:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
</head>
<body>
<div id="root"></div>
<script src="bundle.js"></script>
</body>
</html>
我们的React应用程序将被注入到root div 元素中。所有应用程序的JavaScript代码最终将被捆绑在一起,成为build 文件夹中index.html 旁边的一个名为bundle.js 的文件。
添加React和TypeScript
在终端中添加以下命令来安装React、TypeScript和React类型:
npm install react react-dom
npm install --save-dev typescript
npm install --save-dev @types/react @types/react-dom
TypeScript的配置是一个名为tsconfig.json 的文件。让我们在我们项目的根目录下创建这个文件,内容如下:
{
"compilerOptions": {
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"allowSyntheticDefaultImports": true,
"skipLibCheck": true,
"esModuleInterop": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react"
},
"include": ["src"]
}
我们只打算在我们的项目中使用TypeScript进行类型检查。我们最终将使用Babel来进行代码转译。因此,我们的tsconfig.json 中的编译器选项主要集中在类型检查,而不是代码转译。
下面是对我们所使用的设置的解释:
lib:在类型检查过程中要包括的标准类型。在我们的例子中,我们选择使用浏览器DOM的类型以及最新版本的ECMAScript。allowJs:是否允许对JavaScript文件进行编译。allowSyntheticDefaultImports:这允许在类型检查过程中从没有默认输出的模块中默认导入。skipLibCheck:是否跳过所有类型声明文件(*.d.ts)的类型检查。esModuleInterop:这使得与Babel兼容。strict:这将类型检查的级别设置为非常高。当这一点是true,该项目被称为在严格模式下运行。forceConsistentCasingInFileNames:确保在类型检查过程中,引用的文件名的大小写是一致的。moduleResolution:如何解决模块的依赖性,这对我们的项目来说是节点。resolveJsonModule:这使得模块可以在.json,这对配置文件很有用。noEmit:是否在编译过程中抑制TypeScript生成的代码。这在我们的项目中是true,因为Babel将生成JavaScript代码。jsx:是否支持JSX在.tsx文件。include:这些是TypeScript要检查的文件和文件夹。在我们的项目中,我们已经指定了src文件夹中的所有文件。
添加一个根React组件
让我们在src 文件夹中的index.tsx 文件中创建一个简单的React组件。这最终将显示在index.html :
import React from "react";
import ReactDOM from "react-dom";
const App = () => (
<h1>My React and TypeScript App!</h1>
);
ReactDOM.render(
<App />,
document.getElementById("root")
);
添加Babel
我们的项目将使用Babel将我们的React和TypeScript代码转换为JavaScript。让我们把Babel和必要的插件作为开发依赖来安装:
npm install --save-dev @babel/core @babel/preset-env @babel/preset-react @babel/preset-typescript @babel/plugin-transform-runtime @babel/runtime
下面是对我们刚刚安装的软件包的解释:
@babel/core:顾名思义,这就是Babel的核心库。@babel/preset-env:这是一个插件集合,允许我们使用最新的JavaScript特性,但仍然针对不支持这些特性的浏览器。@babel/preset-react:这是一个插件集合,使Babel能够将React代码转化为JavaScript。@babel/preset-typescript:这是一个插件,使Babel能够将TypeScript代码转化为JavaScript。@babel/plugin-transform-runtime和 : 这些是使我们能够使用 和 JavaScript 功能的插件。@babel/runtimeasyncawait
配置Babel
Babel是在一个名为.babelrc 的文件中配置的。让我们在我们项目的根目录下创建这个文件,内容如下:
{
"presets": [
"@babel/preset-env",
"@babel/preset-react",
"@babel/preset-typescript"
],
"plugins": [
[
"@babel/plugin-transform-runtime",
{
"regenerator": true
}
]
]
}
这个配置告诉Babel使用我们已经安装的插件。
添加提示
我们将在项目中使用 ESLint在我们的项目中。ESLint可以帮助我们找到有问题的编码模式或不遵守特定风格准则的代码。
那么,让我们把ESLint和我们将要需要的插件一起作为开发依赖项安装:
npm install --save-dev eslint eslint-plugin-react eslint-plugin-react-hooks @typescript-eslint/parser @typescript-eslint/eslint-plugin
下面是对我们刚刚安装的软件包的解释:
eslint:这是ESLint的核心库。eslint-plugin-react:这包含一些React代码的标准提示规则。eslint-plugin-react-hooks:这包括一些React钩子代码的提示规则。@typescript-eslint/parser:这允许TypeScript代码被刷新。@typescript-eslint/eslint-plugin:这包含了一些TypeScript代码的标准提示规则。
ESLint可以在项目根部的.eslintrc.json 文件中进行配置。
让我们创建包含以下内容的配置文件:
{
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaVersion": 2018,
"sourceType": "module"
},
"plugins": [
"@typescript-eslint",
"react-hooks"
],
"extends": [
"plugin:react/recommended",
"plugin:@typescript-eslint/recommended"
],
"rules": {
"react-hooks/rules-of-hooks": "error",
"react-hooks/exhaustive-deps": "warn",
"react/prop-types": "off"
},
"settings": {
"react": {
"pragma": "React",
"version": "detect"
}
}
}
所以,我们已经将ESLint配置为使用TypeScript解析器,并将标准的React和TypeScript规则作为基础规则集。我们明确地添加了两个React钩子规则,并抑制了react/prop-types 规则,因为道具类型在React与TypeScript项目中不相关。我们还告诉ESLint检测我们所使用的React的版本。
添加webpack
Webpack是一个流行的工具,我们可以用它来把所有的JavaScript代码捆绑到我们的index.html 所期望的bundle.js 文件中。让我们来安装核心的webpack库以及它的命令行接口:
npm install --save-dev webpack webpack-cli @types/webpack
Webpack有一个网络服务器,我们将在开发过程中使用。让我们来安装这个:
npm install --save-dev webpack-dev-server @types/webpack-dev-server
我们需要一个webpack插件,babel-loader ,以便让Babel将React和TypeScript代码转译成JavaScript。让我们安装这个:
npm install --save-dev babel-loader
Webpack的配置文件是基于标准的JavaScript。但是,如果我们安装一个叫ts-node 的包,我们就可以使用TypeScript。让我们安装这个:
npm install --save-dev ts-node
Webpack是通过一个叫做webpack.config.ts 的文件来配置的。让我们在项目的根目录下创建这个文件,内容如下:
import path from "path";
import { Configuration } from "webpack";
const config: Configuration = {
entry: "./src/index.tsx",
module: {
rules: [
{
test: /\.(ts|js)x?$/,
exclude: /node_modules/,
use: {
loader: "babel-loader",
options: {
presets: [
"@babel/preset-env",
"@babel/preset-react",
"@babel/preset-typescript",
],
},
},
},
],
},
resolve: {
extensions: [".tsx", ".ts", ".js"],
},
output: {
path: path.resolve(__dirname, "build"),
filename: "bundle.js",
},
devServer: {
static: path.join(__dirname, "build"),
compress: true,
port: 4000,
},
};
export default config;
以下是这个配置文件中的关键部分:
entry字段告诉Webpack从哪里开始寻找要捆绑的模块。在我们的项目中,这就是index.tsx。module字段告诉Webpack将如何处理不同的模块。我们的项目告诉Webpack使用babel-loader插件来处理扩展名为.js、.ts和.tsx的文件。resolve.extensions字段告诉Webpack在模块解析过程中要以何种顺序寻找何种文件类型。output字段告诉Webpack将我们的代码捆绑在哪里。在我们的项目中,这就是build文件夹中名为bundle.js的文件。devServer字段用于配置Webpack开发服务器。我们告诉它,Web服务器的根是build文件夹,并在端口4000。
在Webpack进程中添加类型检查
Webpack进程目前不会做任何类型检查。我们可以使用一个叫做fork-ts-checker-webpack-plugin 的包来使Webpack进程对代码进行类型检查。这意味着Webpack会通知我们任何类型错误。让我们来安装这个包:
npm install --save-dev fork-ts-checker-webpack-plugin @types/fork-ts-checker-webpack-plugin
让我们把这个添加到webpack.config.ts :
...
import ForkTsCheckerWebpackPlugin from 'fork-ts-checker-webpack-plugin';
const config: Configuration = {
...,
plugins: [
new ForkTsCheckerWebpackPlugin({
async: false,
eslint: {
files: "./src/**/*",
},
}),
],
};
下面是对这些ForkTsCheckerWebpackPlugin 设置的解释:
async:我们将其设置为false,以便Webpack在发出任何代码之前等待类型检查过程的完成。eslint:我们将其设置为指向源文件,这样Webpack就会通知我们任何的linting错误。
添加npm脚本
我们将利用npm脚本在开发模式下启动我们的应用,并构建我们应用的生产版本。让我们在package.json 中添加一个scripts 部分,其中包括以下脚本:
...,
"scripts": {
"start": "webpack serve --open",
"build": "webpack --mode production"
},
...
让我们在终端运行以下命令,在开发模式下启动应用程序:
npm start
几秒钟后,Webpack开发服务器将启动,我们的应用程序将在我们的默认浏览器中打开。

我们将让应用程序运行。
让我们对在index.tsx 中呈现的标题做一个改变。让我们在标题中引用一个叫做today 的变量:
...
const App = () => <h1>My React and TypeScript App! {today}</h1>;
...
当然,这是一个错误,因为我们没有在任何地方声明和初始化today 。Webpack会在终端引发这个类型的错误:
现在让我们通过改变渲染的标题来解决这个问题,引用有效的东西:
const App = () => (
<h1>
My React and TypeScript App!{" "}
{new Date().toLocaleDateString()}
</h1>
);
类型错误将消失,正在运行的应用程序将被更新以包括今天的日期:

现在让我们继续尝试最后的npm脚本。这将产生一个我们的应用程序的生产构建。让我们在终端运行以下命令:
npm run build
几秒钟后,一个名为bundle.js 的文件将出现在build 文件夹中。这个文件包含所有的JavaScript最小化代码,包括React库和React组件的代码。
这就是了!我们的项目现在已经设置好了,可以开始使用。我们的项目现在已经设置好了,可以让我们有效地开发我们的React和TypeScript应用程序。