用webpack从零搭建基于typescript的react项目

前言

跟着油管一个教程做的笔记,看完觉得非常有帮助!这篇文章主要包括以下四个部分,源码

  • 第一步:typescript编译
  • 第二步:webpack解析及打包
  • 第三步:webpack合并及相关问题
  • 第四步:eslint

第一步

1.初始化项目

npm init

2.创建src文件夹,并在里面创建index.html

//  src/index.html
<body>
	<div id="root"></div>
</body>

3.react依赖包

npm i react react-dom

4.ts及相关依赖包

npm i -D typescript @types/react @types/react-dom

因为使用的是ts,所以安装包的时候需要同时安装@type/xxx这样的类型定义,在安装其他包是也是同样的道理。

5.ts配置初始化

tsc --init

这里列举了一些常见配置

{
   "compilerOptions": {
      "target": "es2016" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */,
      "lib": [
         "DOM",
         "ESNext"
      ] /* Specify a set of bundled library declaration files that describe the target runtime environment. */,
      "jsx": "react-jsx" /* 这个一定要有 Specify what JSX code is generated. */,
      "module": "commonjs" /* Specify what module code is generated. */,
      "resolveJsonModule": true /* Enable importing .json files. */,
      "noEmit": true /* Disable emitting files from a compilation. */,
      "isolatedModules": true /* Ensure that each file can be safely transpiled without relying on other imports. */,
      "esModuleInterop": true /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */,
      "forceConsistentCasingInFileNames": true /* Ensure that casing is correct in imports. */,
      "skipLibCheck": true /* Skip type checking all .d.ts files. */
   },
   "include": ["src/**/*"]
}

6.babel依赖包

npm i -D @babel/core @babel/preset-env @babel/preset-react @babel/preset-typescript

7.创建.babelrc进行配置

{
   "presets": [
      "@babel/preset-env",
      [
         "@babel/preset-react",
         {
            "runtime": "automatic"
         }
      ],
      "@babel/preset-typescript"
   ]
}

8.添加App.tsx根组件和入口index.tsx

export const App = () => {
   return (
      <h1>hello!</h1>
   )
}
import ReactDOM from "react-dom"
import { App } from "./App"
ReactDOM.render(<App />, document.getElementById("root"))

到此为止,项目的整体结构如下:

- node_modules
- src
     - App.tsx
     - index.html
     - index.tsx
- .babelrc
- package.json
- package-lock.json
- tsconfig.json

第二步

1.安装webpack相关依赖包

npm i -D webpack webpack-cli webpack-dev-server html-webpack-plugin

2.安装babel loader

npm i -D babel-loader

3.创建webpack文件夹,创建webpack.config.js进行配置

const path = require("path")
const HtmlWebpackPlugin = require("html-webpack-plugin")
module.exports = {
   // 稍微解释下: __dirname表示当前目录,".."表示返回上一级,
   // "./src/index.tsx"表示返回上一级后的当前目录 下的src下的index.tsx
   entry: path.resolve(__dirname, "..", "./src/index.tsx"),
   resolve: {
      extensions: [".tsx", ".ts", ".js"], // 按顺序解析
   },
   module: {
      rules: [
         {
            test: /\.(ts|js)x?$/,
            exclude: /node_modules/,
            use: [
               {
                  loader: "babel-loader",
               },
            ],
         },
      ],
   },
   output: {
      path: path.resolve(__dirname, "..", "./dist"),
      filename: "bundle.js",
   },
   mode: "development",
   plugins: [
      new HtmlWebpackPlugin({
         template: path.resolve(__dirname, "..", "./src/index.html"),
      }),
   ],
}

4.在packjson.json中添加脚本运行命令(--open如果编译成功自动在浏览器打开)。此时就可以通过npm startnpm run build验收成果了

 "start": "webpack serve --config webpack/webpack.config.js --open",
 "build": "webpack --config webpack/webpack.config.js",

5.在src下创建style.css并写入简单样式,然后导入到App,tsx

import "./style.css"

6.安装样式依赖包

npm i -D css-loader style-loader

7.在webpack中进行配置(插入到module下的rules数组中)

{
    test: /\.css$/,
    use: ["style-loader", "css-loader"],
},

8.找一张图片放在src中,然后导入到App,tsx并使用。

import IMAGE from "./test.jpeg"

export const App = () => {
   return (
      <>
       	 ...
         <img src={TEST} alt="test" />
      </>
   )
}

9.此时你会看到一个提示:找不到模块“./test.jpeg”或其相应的类型声明。

10.在src下创建声明文件declarations.d.ts

declare module "*.jpeg"

11.在webpack中进行配置

{
	test: /\.(?:ico|gif|png|jpg|jpeg)$/i,
	type: "asset/resource",
},

12.如果是svg也是同样的道理,先是在declarations.d.ts声明,接着在webpack中配置

 {
	test: /\.(woff(2)?|eot|ttf|otf|svg)$/,
	type: "asset/inline",
 },

到此为止,项目的整体结构如下:

- node_modules
- src
    - App.tsx
    - index.html
    - index.tsx
    - [+]style.css
    - [+]declarations.d.ts
    - [+]test.jpeg
    - [+]test.svg
- [+]webpack
	- [+]webpack.config.js
- .babelrc
- package.json
- package-lock.json
- tsconfig.json

第三步

1.将webpack.config.js改成webpack.common.js,并删除mode选项

2.在webpack文件夹下创建webpack.dev.jswebpack.prod.jswebpack.config.js

// webpack.dev.js
module.exports={
    mode:'development',
    devtool:'cheap-module-source-map' // 定位错误
}

// webpack.prod.js
module.exports = {
   mode: "production",
   devtool: "source-map", // 定位错误
}

3.安装webpack合并依赖包

npm i -D webpack-merge

4.配置webpack.config.js

const { merge } = require("webpack-merge")
const commonConfig = require("./webpack.common.js")
module.exports = (envVars) => {
   const { env } = envVars
   const envConfig = require(`./webpack.${env}.js`)
   const config = merge(commonConfig, envConfig)
   return config
}

5.在packjson.json中修改命令

"start": "webpack serve --config webpack/webpack.config.js --env env=dev",
"build": "webpack --config webpack/webpack.config.js --env env=prod"

6.process.env.NODE_ENV可打印出环境

7.可通过下面方法自定义变量,早dev环境下通过process.env.name就可以打印出haha

// webpack.dev.js
const webpack=require('webpack')
module.exports={
	plugins:[
		new webpack.DefinePlugin({
			'process.env.name':JSON.stringify('haha')
		})
	]
}

8.状态重置问题(更改相关代码保存后,state状态会重置):安装相关依赖并进行配置

npm install -D @pmmmwh/react-refresh-webpack-plugin react-refresh
// webpack.dev.js
const ReactRefreshWebpackPlugin = require("@pmmmwh/react-refresh-webpack-plugin")
module.exports = {
   devServer: {
      hot: true,
      open:true
   },
   plugins: [
      new ReactRefreshWebpackPlugin(),
   ],
}

到此为止,项目结构如下

- node_modules
- src
    - App.tsx
    - index.html
    - index.tsx
    - style.css
    - declarations.d.ts
    - test.jpeg
    - test.svg
- webpack
	- webpack.config.js
	- [+]webpack.common.js
	- [+]webpack.dev.js
	- [+]webpack.prod.js
- .babelrc
- package.json
- package-lock.json
- tsconfig.json

第四步

1.安装eslint依赖包

2.创建并配置.eslintrc.js

module.exports = {
   parser: "@typescript-eslint/parser",
   parserOptions: {
      ecmaVersion: 2020,
      sourceType: "module", // 使能够用import
   },

   //    react版本自动检测
   settings: {
      react: {
         version: "detect",
      },
   },
   // 使用安装好的依赖包
   extends: [
      "plugin:react/recommended",
      "plugin:react-hooks/recommended",
      "plugin:@typescript-eslint/recommended",
   ],
   rules: {
      "@typescript-eslint/no-inferrable-types": "off",
      "no-unused-vars": "off", //不允许无用的变量
      "@typescript-eslint/no-unused-vars": ["error"],
      "@typescript-eslint/no-var-requires": "off",
      "react/prop-types": "off", //因为使用了ts  所以关闭
      "react/jsx-uses-react": "off", // 如果没有导入react不会报错
      "react/react-in-jsx-scope": "off",
      "@typescript-eslint/explicit-module-boundary-types": "off", // 由于可以用interface,所以关掉因为类别没有被精准指定的错误
   },
}

3.在vscode中安装eslint扩展程序

4.在packjson.json中添加一个命令,可以打印整个项目的错误

"lint": "eslint --fix \"./src/**/*.{js,jsx,ts,tsx,json}\""
posted @ 2022-07-20 10:46  sanhuamao  阅读(200)  评论(0编辑  收藏  举报