用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 start
和npm 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.js
、webpack.prod.js
、webpack.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}\""