简介
- 本节介绍如何在开发中搭建一个完整的开发环境。
- 一个完整的开发环境,能统一项目的各种规范。规范统一后,能提高项目开发效率,增强项目规范性和健壮程度等。
- 想详细了解的请移步,社区大佬文章 if 我是前端团队 Leader,怎么制定前端协作规范?
初始化项目
- 新建一个文件夹
chart
(随意命名)。 - 安装
node
。我的版本:
-
运行初始化命令
npm init -y
,-y
在npm
初始化过程一直选择yes
。运行成功后出现package.json
文件,表示npm
项目初始化成功 -
代码编辑器推荐使用
VSCode
代码检查
在开发中有一些问题,是因为开发人员写代码的习惯和粗心造成的。为了避免这些错误,就需要一个工具来实时检测代码。这里使用 ESlint 来作为代码检查的工具。项目中安装:
npm i eslint -D
初始化 ESlint
的配置,在这个过程中会出现许多问题,根据你的选择生成对应的配置。
npx eslint --init
问题和我选择的选项。
- How would you like to use ESLint? > To check syntax, find problems, and enforce code style
- What type of modules does your project use? > JavaScript modules (import/export)
- Which framework does your project use? > None of these
- Does your project use TypeScript? > NO
- Where does your code run? > Browser
- How would you like to define a style for your project > Use a popular style guide
- Which style guide do you want to follow? > Airbnb: github.com/airbnb/java…
- What format do you want your config file to be in? > JavaScript
- Would you like to install them now with npm? > Yes
- Which package manager do you want to use? npm
最后一步使用npm
安装,Airbnb
规则相关的包。
执行完成后生成.eslintrc.js
文件。
module.exports = {
env: {
browser: true,
es2021: true
},
extends: ['airbnb-base'],
parserOptions: {
ecmaVersion: 'latest',
sourceType: 'module'
},
rules: {
'import/prefer-default-export': 0,
'comma-dangle': 0,
semi: 0
}
}
在rules
对象中,把规则值设置为0,取消该规则检测。
现在开始验证ESlint
是否配置完成,在根目录添加src/index.js
和src/drawRect.js
。
// src/index.js
import { drawRect } from './drawRect'
// src/drawRect.js
export function drawRect(svg) {
var rect = document.createElementNS('http://www.w3.org/2000/svg', 'rect')
rect.setAttribute('x', 0)
rect.setAttribute('y', 0)
rect.setAttribute('fill', 'red')
rect.setAttribute('width', 100)
rect.setAttribute('height', 100)
svg.appendChild(rect)
}
执行命令行npx eslint src/drawRect.js
就会检测drawRect.js
文件中的格式。
加上 --fix
选项会修复在规则列表有黄色标记的规则。
执行npx eslint src/drawRect.js --fix
。就会看见var
被修改成了const
,CRLF
换行格式修改为LF
格式。
在 package.json
中添加快捷命令行,方便后续使用。
"scripts": {
"lint": "eslint --ext .js --ignore-path .gitignore .",
"lint:fix": "eslint --fix --ext .js --ignore-path .gitignore ."
},
`--ext` // 指定要检查的文件
`--ignore-path` // 忽略文件 后面跟上git的忽略文件 它们格式是一样的
如果你使用的是VSCode
可以安装ESlint
插件。
插件会直接在文件中把问题高亮出来。
代码格式化
为了统一编码风格,方便后期维护。需要一个工具来自动格式化文件。这里使用prettier
。
和eslint
一样项目中安装,都需要命令行来启动。这里我们直接在开发工具中安装prettier
插件,在保存时自动格式化。
在根目录创建.prettierrc
的文件,自定义格式化规范。
{
"printWidth": 140,// 每行字符长度,大于换行
"tabWidth": 2,// 缩进空格数
"singleQuote": true,// 是否将双引号转换为单引号
"semi": false,// 语句末尾是否带分号
"trailingComma": "none",// 末尾是否带逗号 none 没有逗号 | all 尾随逗号
"arrowParens": "avoid",// 箭头函数参数周围包含括号 always有括号 | avoid无括号
}
在根目录创建.vscode/settings.json
的文件,配置开发工具保存时自动格式化。
{
"editor.formatOnSave": true // 每次保存的时候自动格式化
}
为了更好的配合eslint
检测,添加规则包。
npm i eslint-config-prettier eslint-plugin-prettier -D
eslint-config-prettier
:关闭eslint
中与prettier
相互冲突的规则。eslint-plugin-prettier
:赋予eslint
用prettier
格式化代码的能力。
修改.eslintrc.js
文件。
// extends: ['airbnb-base'],
extends: ['airbnb-base', 'plugin:prettier/recommended'],
代码构建
我们搭建的是一个图表库,需要打包体积小,打包工具配置简洁。这里使用 Rollup 来作为打包器。
安装Babel
核心包,转换代码。
npm i @babel/core @babel/cli @babel/preset-env -D
添加一个.babelrc
文件,进行babel
配置。
{
"presets": [
[
"@babel/preset-env",
{
"useBuiltIns": "entry",
"corejs": "3.6.4"
}
]
],
"exclude": "node_modules/**"
}
安装 rollup
打包工具。
npm i rollup -D
需要 rollup 用 Babel 对代码进行编译,安装 @rollup/plugin-babel
。
npm i @rollup/plugin-babel -D
需要保证打包过程能正确加载文件,安装 @rollup/plugin-node-resolve
。
npm i @rollup/plugin-node-resolve -D
启动服务和热更新服务,安装 rollup-plugin-serve
、rollup-plugin-livereload
。
npm i rollup-plugin-serve rollup-plugin-livereload -D
自动生成.html
文件,安装@rollup/plugin-html
npm i @rollup/plugin-html -D
使用环境变量,安装cross-env
npm i cross-env -D
每次打包删除上一次的文件,安装rimraf
npm i rimraf -D
新建 rollup.config.js
文件,输入以下的内容:
import { babel } from '@rollup/plugin-babel'
// 打包过程能正确加载文件
import { nodeResolve } from '@rollup/plugin-node-resolve'
import html from '@rollup/plugin-html'
// 开发服务器
import serve from 'rollup-plugin-serve'
// 热更新加载
import livereload from 'rollup-plugin-livereload'
// true 开发环境
const isDev = process.env.NODE_ENV !== 'production'
export default {
input: 'src/index.js', // 打包入口
output: [
// {
// file: 'dist/cjs/index.js', // 对于 Nodejs,打包成 commonjs
// format: 'cjs'
// },
// {
// file: 'dist/es/index.js', // 对于浏览器,打包成 ES module
// format: 'es'
// },
{
file: 'dist/index.js',
name: 'sp',
format: 'umd' // 对于 Nodejs 和浏览器,打包成混合模式
}
],
plugins: [
nodeResolve(),
babel({ babelHelpers: 'bundled' }), // 使用 babel 插件
html({
fileName: 'index.html',
publicPath: './',
attributes: { html: { lang: 'en' }, link: null, script: null }
}),
// 服务
isDev &&
serve({
open: true, // 自动打开页面
port: 8090,
openPage: '/dist/index.html'
}),
// 服务热更新
isDev && livereload()
]
}
在package.json
中添加命令。
"scripts": {
"dev": "rollup -c -w",
"build": "rimraf -rf ./dist && cross-env NODE_ENV=production rollup -c",
...
},
-c
指定 rollup 的配置文件。-w
监听源文件是否有改动,如果有改动,重新打包。
修改src/index.js
文件。
import { drawRect } from './drawRect'
const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg')
svg.setAttribute('width', 400)
svg.setAttribute('height', 400)
svg.setAttribute('viewBox', [0, 0, 400, 400])
document.body.appendChild(svg)
drawRect(svg)
执行命令就可以启动服务或打包。
npm run dev || npm run build
代码测试
在一般的公司中都不会使用,(开发时间都不够,谁有时间写单元测试)。不过一个优秀的单元测试可以最大程度的减少问题。
这里使用 Jest 和 Jest Electron 来搭建测试环境。
npm i jest jest-electron -D
添加jest.config.js
文件,配置环境。
module.exports = {
testMatch: ['**/__tests__/**/*.spec.js'], // 只测试后缀为 .spec.js 的文件
runner: 'jest-electron/runner', // 指定测试的 runner
testEnvironment: 'jest-electron/environment' // 制定测试的环境
}
添加 __tests__/index.spec.js
测试文件。
import { drawRect } from '../src/drawRect'
describe('test', () => {
test('drawRect()', () => {
const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg')
svg.setAttribute('width', 400)
svg.setAttribute('height', 400)
svg.setAttribute('viewBox', [0, 0, 400, 400])
document.body.appendChild(svg)
drawRect(svg)
expect(svg.getElementsByTagName('rect').length).toBe(1)
})
})
在 package.json
中添加命令。
"scripts": {
...
"test": "jest --coverage",
"test-live":"cross-env DEBUG_MODE=1 jest --coverage",
...
},
--coverage
生成测试报告文件。
兼容eslint
,安装 eslint-plugin-jest
。
npm i eslint-plugin-jest -D
修改.eslintrc.js
文件。
module.exports = {
env: {
browser: true,
es2021: true,
'jest/globals': true
},
extends: ['airbnb-base', 'plugin:prettier/recommended'],
plugins: ['jest'],
parserOptions: {
ecmaVersion: 'latest',
sourceType: 'module'
},
rules: {
// 这里添加一行规则把这条规则隐藏
'import/prefer-default-export': 0,
'comma-dangle': 0,
semi: 0,
'prettier/prettier': 0
}
}
执行 npm run test
。
执行 npm run test-live
,会打开一个基于 Electron 真实的浏览器。
添加版本管理
这里和大部分人一样使用 Git 作为版本库。我是在github
上创建好项目,拉取到本地的,所以不用初始化Git
。
创建一个名为.gitignore
的文件,指定不加入版本管理的文件。就是提交时忽略这些文件。
node_modules
*.log*
yarn.lock
package-lock.json
# Build
dist
lib
esm
# test
coverage
不是每个人都会遵守,人为约定的规范。所以在提交的过程中,强制对加入暂存区代码进行检查,并且规范提交信息。
需要一些工具:
commitlint
:对你的提交信息进行检查。lint-staged
:对新加入暂存区的文件进行指定的操作。简单理解就是过滤本地文件,只选中暂存区的文件,然后对这些文件进行命令行操作,如eslint --fix
。husky
:让你创建勾子(Hook),比如创建在git-commit
和git-push
阶段执行勾子。cz-conventional-changelog
标准提交提示。
- 安装
commitlint
和添加配置。
npm install @commitlint/config-conventional @commitlint/cli -D
修改package.json
文件,添加如下配置。
"commitlint": {
"extends": [
"@commitlint/config-conventional"
]
},
这里使用的 config-conventional
规则,具体可以参考这里。
- 安装
lint-staged
和添加配置。
npm i lint-staged -D
修改package.json
文件。
"lint-staged": {
"*.js": ["npm run lint:fix"]
},
对暂存区的文件执行npm run lint:fix
。
- 初始化
husky
并 安装包。
npx husky-init && npm i
生成.husky
文件夹,并安装husky
包。
添加钩子:pre-commit
(在提交前执行后面的命令)和 commit-msg
(在提交的时候执行后面的命令)。
npx husky add .husky/pre-commit 'npx lint-staged'
npx husky add .husky/commit-msg 'npx --no-install commitlint --edit "$1"'
在windiws
系统中无法直接执行命令。我们手动创建pre-commit
和commit-msg
文件。
// .husky/pre-commit
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
npx lint-staged
// .husky/commit-msg
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
npx --no-install commitlint --edit "$1"
执行 git add .
时,会使用lint-staged
的配置对暂存区文件执行npm run lint:fix
。
执行 git commit -m
时,会验证提交信息是否合格,不合格不能提交。格式git commit -m "chore: 初始化"
规则
我正在参与掘金技术社区创作者签约计划招募活动,点击链接报名投稿。