本文用于记录我在开发中,项目用到的一些辅助工具的总结,比较全的配置参考了element-plus项目
代码检查
typescripteslint
@typescript-eslint/eslint-plugin // 兼容typescript
@typescript-eslint/parser
eslint-define-config // 为eslint配置添加提示
eslint-plugin-jest // 处理jest
eslint-config-prettier // 兼容prettier
eslint-plugin-react // 处理react jsx
eslint-plugin-react-hooks // 处理hooks
eslint-plugin-vue // 处理.vue文件
以下是一些简单的配置
const { defineConfig } = require('eslint-define-config')
module.exports = defineConfig({
'extends': [
'eslint:recommended',
'plugin:@typescript-eslint/eslint-recommended',
'plugin:@typescript-eslint/recommended',
'plugin:jest/recommended',
'prettier'
],
'parserOptions': {
'parser': '@typescript-eslint/parser',
'ecmaVersion': 2021,
'sourceType': 'module'
},
'plugins': ['@typescript-eslint', 'jest'],
'rules': {},
'overrides': [
{
'files': ['packages/web/src/**'],
'extends': ['plugin:react/recommended'],
'rules': {
'react/react-in-jsx-scope': 'off',
'no-useless-escape': 'off'
}
},
{
'files': ['*.vue'],
'extends': ['plugin:vue/vue3-recommended'],
'parser': 'vue-eslint-parser',
'env': {
'vue/setup-compiler-macros': true
},
'rules': {
'vue/script-setup-uses-vars': 'error'
}
},
{
'files': ['*.js'],
'rules': {
'no-undef': 'off',
'@typescript-eslint/no-var-requires': 'off'
}
}
]
})
jestts-jest// 允许jest中使用ts@vue/vue3-jest// vue3
"@testing-library/react": "^12.1.2",
"@testing-library/jest-dom": "^5.16.1",
"@testing-library/react-hooks": "^7.0.2",
jest的简单配置
import type { Config } from '@jest/types'
const config: Config.InitialOptions = {
preset: 'ts-jest/presets/js-with-ts',
clearMocks: true,
testEnvironment: 'jsdom',
modulePathIgnorePatterns: ['<rootDir>/package.json'],
moduleNameMapper: {
'@/(.*)$': '<rootDir>/src/$1'
},
rootDir: '.',
resetMocks: false,
globals: {
'ts-jest': {
tsconfig: 'tsconfig.json'
}
}
}
export default config
prettier用于代码样式优化pretty-quick辅助工具
stylelint样式格式管理工具,官网
pnpm
包管理工具
提交时代码检查
lint-staged只处理本次修改的部分,与git挂钩@commitlint/config-conventional、@commitlint/cligit commit的message提交规范husky在script中添加"prepare": "husky install",用于npm install时自动创建husky.sh文件
使用类似npx husky add .husky/pre-commit "npx lint-staged"创建提交的钩子
package.json中
"lint-staged": {
"*.{js,jsx,less,md,json}": "prettier --write",
"*.ts?(x)": [
"prettier --parser=typescript --write"
],
"packages/*/src/*": "eslint --ext .js,.ts,.tsx"
},
使用npx husky add .husky/commit-msg "npx --no-install commitlint --edit $1"创建提交说明规范
日志生成工具
conventional-changelog-cli目前2.0版本只能针对git中tag版本输出日志,且同一个tag同一天中并非按时间顺序输出。更多参考 在scripts中写入
"changelog": "conventional-changelog -p angular -i CHANGELOG.md -s -r 0 -n ./changelog-option.js"
/*配置项说明:
-p angular 指定风格,也可以用custom-config
-i CHANGELOG.md 指定输出的文件名称
-s -r 0 指定增量更新,不会覆盖以前的更新日志
-n ./changelog-option.js 指定自定义配置
*/
// changelog-option.js中
const compareFunc = require('compare-func')
const message = {
'feat': '✨ Features | 新功能',
'fix': '🐛 Bug Fixes | Bug 修复',
'perf': '⚡ Performance Improvements | 性能优化',
'revert': '⏪ Reverts | 回退',
'docs': '📝 Documentation | 文档',
'style': '💄 Styles | 风格',
'refactor': '♻ Code Refactoring | 代码重构',
'test': '✅ Tests | 测试',
'build': '👷 Build System | 构建',
'ci': '🔧 Continuous Integration | CI 配置',
'chore': '🎫 Chores | 其他更新'
}
module.exports = {
writerOpts: {
transform: (commit, context) => {
let discard = true
const issues = []
commit.notes.forEach(note => {
note.title = 'BREAKING CHANGES'
discard = false
})
if (
!['feat', 'fix', 'perf', 'revert'].includes(commit.type) &&
discard
) {
return // 此处过滤不是按照commitlint规则输出的日志
} else {
// custom-config模式只会输出header
// commit.header = commit.header.replace(
// commit.type,
// message[commit.type]
// )
commit.type = message[commit.type]
}
if (commit.scope === '*') {
commit.scope = ''
}
if (typeof commit.hash === 'string') {
commit.hash = commit.hash.substring(0, 7)
}
if (typeof commit.subject === 'string') {
let url = context.repository
? `${context.host}/${context.owner}/${context.repository}`
: context.repoUrl
if (url) {
url = `${url}/issues/`
// Issue URLs.
commit.subject = commit.subject.replace(
/#([0-9]+)/g,
(_, issue) => {
issues.push(issue)
return `[#${issue}](${url}${issue})`
}
)
}
if (context.host) {
// User URLs.
commit.subject = commit.subject.replace(
/\B@([a-z0-9](?:-?[a-z0-9/]){0,38})/g,
(_, username) => {
if (username.includes('/')) {
return `@${username}`
}
return `[@${username}](${context.host}/${username})`
}
)
}
}
// remove references that already appear in the subject
commit.references = commit.references.filter(
reference => issues.indexOf(reference.issue) === -1
)
return commit
},
groupBy: 'type',
commitGroupsSort: 'title',
commitsSort: ['scope', 'subject'],
noteGroupsSort: 'title',
notesSort: compareFunc
}
}
构建工具
babelbabel-loader@babel/core@babel/preset-env@babel/preset-typescript一般用上这几个即可,另外其它框架使用其对于的,比如react@babel/preset-react
// .babelrc
{
"presets": [
"@babel/preset-env",
[
"@babel/preset-react",
{
"runtime": "automatic" // react17jsx不需要引入React
}
],
"@babel/preset-typescript"
]
}
-
vite@vitejs/plugin-react@vitejs/plugin-vuevite-plugin-style-importantd/element/vant的按需加载工具
import { AntdResolve, createStyleImportPlugin } from 'vite-plugin-style-import' plugins: [ createStyleImportPlugin({ resolves: [AntdResolve()] }) ] -
webpackwebpack-cli提供配置文件webpack-dev-server本地服务webpack-bundle-analyzer构建后文件大小视图html-webpack-pluginhtml解析- 各种loader
{
test: /.(ts|tsx)$/,
exclude: /node_modules/,
use: ['babel-loader'] // babel处理,如果有.babelrc文件则会自动启用
},
{
test: /.less$/,
exclude: /node_modules/,
use: [
'style-loader', // 在js中引用css
{
loader: 'css-loader', // 处理css中的import/url图片等
options: {
modules: true // css模块化
}
},
// 可以添加postcss-loader做兼容处理
'less-loader' // 可以处理less
]
},
{
test: /.(png|jpg)/,
exclude: /node_modules/,
use: [
{
loader: 'url-loader',// 配合file-loader处理js中的图片文件资源
options: {
limit: 16000, // 大于此则使用file-loader处理成静态资源,小于则base64处理
name: 'img/[name].[hash:8].[ext]'
}
}
]
}
其它
ts-nodenode环境允许ts执行rimrafscripts删除文件nodemonnode环境热更新concurrently按顺序执行scripts命令cross-envscripts修改环境变量- 根目录下
.npmrc文件用来设置当前项目的npm配置。例如文件内配置registry=http://registry.npm.taobao.org/则npm i时会启用该仓库镜像地址。如果使用pnpm配置shamefully-hoist=true时会将依赖包引用平铺至node_modules目录下,参考 - 根目录下
.nvmrc文件(需要全局安装了nvm),在进入该目录下执行nvm use则会使用当前配置的node版本