2021-07-08 Webpack集成React和TypeScript的两种方案

1,381 阅读1分钟

由于Webpack只支持解析js和json文件,对于React中JSX和ts文件不支持,这时候就要用到loader整个强大的转换器功能了,这里有两种方法一种是使用ts-loader将ts和tsx解析成js文件;另外一种是使用babel-loader+@babel/preset-typesrcipt

初始化项目

mkdir webpack-react-ts
cd webpack-react-ts

yarn init -y

安装依赖

这里的依赖主要有react、react-dom以及他们对应的@types/react、@types/react-dom等还有webpack相关的依赖

yarn add react @types/react react-dom @types/react-dom
yarn add webpack@4.43.0 webpack-cli@3.3.12 webpack-dev-server@3.11.0 -D

配置webpack.config.js文件

测试文件:

// index.tsx

import ReactDOM from "react-dom";
import React from "react"; // 这个地方有区别下文提到
import App from "./App";

ReactDOM.render(<App />, document.getElementById("root"));


// App.tsx

import React from "react";
import Hello from "./Hello";
function App() {
  return (
    <div>
      <p>Hello, React</p>
      <Hello name="小徐" age={26} />
    </div>
  );
}
export default App;

// Hello.tsx

import React, { useEffect } from "react";

interface HelloProps {
  name: string;
  age: number;
}
const Hello: React.FC<HelloProps> = (props: HelloProps) => {
  useEffect(() => {}, []);
  const changeName = () => {
    console.log(props.name);
  };
  return (
    <div>
      <p>姓名:{props.name}</p>
      <p>年龄:{props.age}</p>
      <button onClick={changeName}>改变姓名</button>
    </div>
  );
};
export default Hello;


基础配置如下:

const path = require("path");
const { HotModuleReplacementPlugin } = require("webpack");
const HtmlWebpackPlugin = require("html-webpack-plugin");

module.exports = {
  entry: "./src/index.tsx",
  output: {
    path: path.resolve(__dirname, "dist"),
    filename: "[name].js"
  },
  mode: "development",
  devtool: "cheap-module-eval-source-map",
  devServer: {
    contentBase: path.join(__dirname, "dist"),
    port: 8080,
    hot: true,
    open: true
  },
  resolve: {
    extensions: [".tsx", ".ts", ".js"]
  },
  module: {
      ...这里配置有两种方法
  },
  plugins: [
    new HotModuleReplacementPlugin(),
    new HtmlWebpackPlugin({
      template: "./src/index.html"
    })
  ]
};

此外tsconfig.json的配置如下:

{
  "compilerOptions": {
    "target": "es5",
    "module": "commonjs",
    "allowJs": true,
    "jsx": "react-jsx",
    "outDir": "./dist/",
    "noImplicitAny": true,
    "moduleResolution": "node",
    "esModuleInterop": true,
    "sourceMap": true
  }
}

方法一:使用ts-loader解析ts和tsx文件

安装ts-loader要注意和webpack的版本,这里webpack4对应的ts-loader@8,不用安装与babel相关的loader了

yarn add ts-loader@8 -D 

这里不需要在引入import React from "react"

webpack.config.js配置文件里修改loader

module:{
    rules: [
       {
        test: /\.tsx?$/,
        use: "ts-loader",
        exclude: /node_modules/
      }
    ]
}

方法二:继续使用babel-loader+预设@babel/preset-typescript

配置.babelrc文件如下:

{
  "presets": [
    [
      "@babel/preset-env",
      {
        "useBuiltIns": "usage"
      }
    ],
    [
      "@babel/preset-react",
      {
        "runtime": "automatic" // 自动引入React
      }
    ],
    "@babel/preset-typescript"
  ]
}

安装babel相关loader

yarn add @babel/core @babel/preset-env babel-loader @babel/preset-react @babel/preset-typescript -D

这里也可以不需要在引入import React from "react",只需要配置下.babelrc文件中的runtime: automatic自动引入

webpack.config.js配置文件里修改loader

module: {
    rules: [
      {
        test: /\.(j|t)sx?$/,
        include: [path.resolve(__dirname, "src")],
        use: ["babel-loader"]
      }
    ]
  },

启动npx webpack-dev-server就可以看到页面了