工作中搭建开发环境这种事情基本上都会使用公司已有的工具进行搭建,但是作为程序员在家手动捣鼓一些技术也是常有的事儿,这里记录下自己的一次开发环境搭建过程,以备后续查询。
明确项目依赖项
- 使用sass写样式
- typescript进行类型声明、检查
- eslint对代码进行规范检查
- react作为基础开发
- 对git的commit进行提交前的规范
- 环境变量可配置。使用.env文件控制环境变量
- 开发环境热更新
前情提要
测试环境使用的是
- pnpm 8.3.1
- node v18.15.0
- VSCode
测试项目文件树
.
├── .babelrc.js
├── .env
├── .eslintrc.js
├── .gitignore
├── .husky
│ ├── _
│ │ └── husky.sh
│ └── commit-msg
├── commitlint.config.js
├── package.json
├── pnpm-lock.yaml
├── public
│ └── index.html
├── src
│ ├── index.tsx
│ ├── test.module.scss
│ └── test.tsx
├── tsconfig.json
├── typings
│ └── index.d.ts
└── webpack.config.js
初始化项目
pnpm init
git init # husky自动安装需要git
安装依赖
依赖有很多,这里拆开来记录
.env配置
使用.env
文件配置环境变量需要安装dotenv-cli
,在package.json
的scripts
中的命令中使用
// 比如
scripts: {
start: 'dotenv -e .env 其他的项目启动命令'
}
以将.env
文件中的变量赋值到process.env
中
pnpm i -D dotenv-cli
webpack
除了基本的webpakck
,还想使用其server
服务以在开发环境热更新项目,所以还需要webpack-dev-server
pnpm i -D webpack webpack-dev-server webpack-cli
解析sass
解析sass的时候需要三种依赖,分别是style-loader
、css-loader
、sass-loader
sass-loader
用来编译.scss
、.sass
文件为css
css-loader
会对@import
和url()
进行处理,就像 js 解析import/require()
一样。且可配置CSS Module
style-loader
将css
插入到dom
中sass
解析sass
语法
pnpm i -D sass style-loader css-loader sass-loader
解析ts、tsx
使用babel-loader
解析ts
、tsx
。那就需要安装
@babel/core
babel-loader
@babel/preset-typescript
pnpm i -D @babel/core babel-loader @babel/preset-typescript
解析react
因为要使用react
框架进行项目开发,所以react
的依赖包必不可少。还有需要让react
的jsx
可以被编译,所以解析react
总共需要的依赖有
react
react-dom
@babel/preset-react
编译jsx
@types/react
@types/react-dom
pnpm i -D react react-dom @babel/preset-react @types/react @types/react-dom
代码规范检查
一般使用eslint
进行代码规范检查。可以去官网查看自动下载安装并配置.eslintrc.js
文件的命令,这里举出npm
的命令npm init @eslint/config
。但是本次测试环境使用的是pnpm
,不妨使用pnpm init @eslint/config
命令看看是否可行。
啊哦,不行的。不过有给出另一个命令,可以执行试试看。
pnpm create @eslint/config
根据图片可以看到,根据需要选完对应的选项后,并选择pnpm
立即安装,就会自动去下载
@typescript-eslint/eslint-plugin
@typescript-eslint/parser
eslint
eslint-plugin-react
且会在项目根目录中生成.eslintrc.js
文件。
另外,考虑到平时的代码开发,在编译的时候就会有检查,所以还需要安装eslint-webpack-plugin
搭配webpack
使用
pnpm i -D eslint-webpack-plugin
git commit提交规范检查
使用husky
控制git hooks
在对应生命周期需要执行的脚本,commitlint
进行规范检查。
其中@commitlint/config-conventional
是commitlint
官方给的一个常用配置
pnpm i -D husky @commitlint/cli @commitlint/config-conventional
文件配置
配置过程中需要注意的事项都在文件中有注释,可以关注下。
package.json
将.env
文件中的变量赋值给process.env
,然后使用webpack-dev-server
启动项目
"scripts": {
"start": "dotenv -e .env webpack-dev-server"
},
完整的package.json
文件内容如下。可以直接拿过去用,但是husky
的commit-msg
需要自己手动或使用命令添加
{
"name": "test-dev",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"start": "dotenv -e .env webpack-dev-server",
"prepare": "husky install"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"@babel/core": "^7.22.5",
"@babel/preset-react": "^7.22.5",
"@babel/preset-typescript": "^7.22.5",
"@commitlint/cli": "^17.6.5",
"@commitlint/config-conventional": "^17.6.5",
"@types/react": "^18.2.11",
"@types/react-dom": "^18.2.4",
"@typescript-eslint/eslint-plugin": "^5.59.9",
"@typescript-eslint/parser": "^5.59.9",
"babel-loader": "^9.1.2",
"css-loader": "^6.8.1",
"dotenv-cli": "^7.2.1",
"eslint": "^8.42.0",
"eslint-plugin-react": "^7.32.2",
"eslint-webpack-plugin": "^4.0.1",
"husky": "^8.0.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"sass": "^1.63.3",
"sass-loader": "^13.3.2",
"style-loader": "^3.3.3",
"webpack": "^5.86.0",
"webpack-cli": "^5.1.4",
"webpack-dev-server": "^4.15.1"
}
}
.env
# 给webpack-dev-server用
PORT=9000
# 给webpack的mode属性用
MODE=development
.eslintrc.js
这里先配置下.eslintrc.js
,避免配置下面的文件时,文件爆红,还以为发生了什么可怕的事情?
module.exports = {
env: {
browser: true,
es2021: true,
},
extends: [
"eslint:recommended",
"plugin:@typescript-eslint/recommended",
"plugin:react/recommended",
// react17之后使用jsx函数实现jsx到dom的转换
"plugin:react/jsx-runtime",
],
parser: "@typescript-eslint/parser",
parserOptions: {
ecmaVersion: "latest",
sourceType: "module",
},
plugins: ["@typescript-eslint", "react"],
// 忽略根目录下的所有以.js为后缀的文件。即不对其进行检查
ignorePatterns: ["/*.js"],
rules: {},
};
webpack.config.js
const path = require("path");
const extensions = [".tsx", ".ts", ".js", ".jsx"];
const ESLintWebpackPlugin = require("eslint-webpack-plugin");
module.exports = {
mode: process.env.MODE, // .env文件里来的
entry: "./src/index.tsx",
output: {
filename: "bundle.js",
path: path.resolve(__dirname, "dist"),
},
module: {
rules: [
{
test: /\.scss$/,
exclude: /node_modules/,
use: [
"style-loader",
{
loader: "css-loader",
options: {
modules: {
localIdentName: "[name]__[local]--[hash:base64:5]",
},
},
},
"sass-loader",
],
},
{
test: /\.(ts|tsx)$/,
exclude: /node_modules/,
use: "babel-loader",
},
],
},
resolve: {
extensions,
},
devServer: {
open: true,
port: process.env.PORT,
client: {
overlay: {
// 当有警告信息时不显示到页面上。可以制造令eslint发出警告的代码测试效果
warnings: false,
},
},
},
plugins: [
/*
下面的options配置与.eslintrc.js文件的关系可以理解为
- .eslintrc.js是给eslint用的。eslint会在整个项目上使用该配置,前提是使用eslint命令
- options配置是给eslint-webpack-plugin用的。
- eslint-webpack-plugin插件内部会在options配置的基础上使用.eslintrc.js文件
- 假如要检查.ts文件,eslint-webpack-plugin的options没有配置.ts文件的检查,
则.eslintrc.js配置就不会在.ts文件上起效。所以如果想要在编译时检查除了.js之外的其他文件,
需要手动配置options选项
*/
new ESLintWebpackPlugin({
// 编译时要检查的根目录
context: path.resolve(__dirname, "src"),
// 编译时要检查的文件后缀
extensions,
}),
],
};
这里eslint-webpack-plugin
的options
配置与.eslintrc.js
文件之间的关系理解如下
options配置与.eslintrc.js文件的关系可以理解为
- .eslintrc.js是给eslint用的。eslint会在整个项目上使用该配置,前提是使用eslint命令
- options配置是给eslint-webpack-plugin用的。
- eslint-webpack-plugin插件内部会在options配置的基础上使用.eslintrc.js文件
- 假如要检查.ts文件,eslint-webpack-plugin的options没有配置.ts文件的检查,
则.eslintrc.js配置就不会在.ts文件上起效。所以如果想要在编译时检查除了.js之外的其他文件,
需要手动配置options选项
.babelrc.js
module.exports = {
presets: [
[
"@babel/preset-react",
{
// react17之后,使用jsx函数进行jsx到dom的转换。可以不用在.tsx文件中使用`import React from 'react',也可以运行代码`
runtime: "automatic",
},
],
"@babel/preset-typescript",
],
};
tsconfig.json
配置的时候,如果文件爆红,可以先注释掉include
属性。因为代码文件还没有创建,typescript
识别不到。
{
"compilerOptions": {
"jsx": "react-jsx" // react17之后,使用jsx函数进行jsx到dom的转换。可以不用在.tsx文件中使用`import React from 'react',也可以运行代码`
},
// 哪些文件可被ts识别。
"include": ["src", "typings"]
}
commilint.config.js
module.exports = { extends: ["@commitlint/config-conventional"] };
husky
husky这边没有配置文件,但是需要安装脚本。操作如下
根据图片执行命令pnpm dlx husky-init && pnpm install
,会在根目录生成
.husky
├── _
│ ├── .gitignore
│ └── husky.sh
└── commit-msg
其中
.gitignore
文件需要被删除,否则无法上传到远端commit-msg
的位置原本是pre-commit
,被删除了,因为我暂时不用?。然后使用下面的命令添加了commit-msg
。
pnpx husky add .husky/commit-msg 'pnpm commitlint --edit "$1"'
各种git hooks
的执行及生命周期可以去git
官网查看了解。
注意:husky
和commitlint
配置完,可以通过下面的命令进行测试
git add .
git commit -m "fdfasdf" # 会在终端报错
git commit -m "feat: fasdfas" # pass
大致结果如下。具体的提交规范,可以去这里查看
测试文件
public/index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app"></div>
<!-- webpack中配置的名称 -->
<script src="bundle.js"></script>
</body>
</html>
typings/index.d.ts
// 将scss文件的import声明为module,避免import对应的.scss文件时爆红
declare module "*.scss"
src/test.module.scss
.color {
color: red;
font-weight: 900;
}
src/test.tsx
import styles from './test.module.scss'
export default function Test() {
return (
<div className={styles.color}>test</div>
)
}
src/index.tsx
import { createRoot } from 'react-dom/client'
import App from './test'
createRoot(document.getElementById('app')).render(<App/>)
测试运行
pnpm start
命令执行完成后,可以在浏览器看到下面的内容
项目的基础配置到此完成,感谢记录的我自己☕️