开发一个简单的图表库 - 搭建开发环境(一)

1,041 阅读8分钟

简介

  • 本节介绍如何在开发中搭建一个完整的开发环境。
  • 一个完整的开发环境,能统一项目的各种规范。规范统一后,能提高项目开发效率,增强项目规范性和健壮程度等。
  • 想详细了解的请移步,社区大佬文章 if 我是前端团队 Leader,怎么制定前端协作规范?

初始化项目

  1. 新建一个文件夹 chart (随意命名)。
  2. 安装node。我的版本:

image.png

  1. 运行初始化命令 npm init -y-ynpm 初始化过程一直选择 yes。运行成功后出现 package.json 文件,表示 npm 项目初始化成功

  2. 代码编辑器推荐使用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.jssrc/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文件中的格式。

image.png

加上 --fix 选项会修复在规则列表有黄色标记的规则。
执行npx eslint src/drawRect.js --fix。就会看见var被修改成了constCRLF换行格式修改为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插件。

image.png

插件会直接在文件中把问题高亮出来。

image.png

代码格式化

为了统一编码风格,方便后期维护。需要一个工具来自动格式化文件。这里使用prettier
eslint一样项目中安装,都需要命令行来启动。这里我们直接在开发工具中安装prettier插件,在保存时自动格式化。

image.png

在根目录创建.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:赋予eslintprettier格式化代码的能力。

修改.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-serverollup-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

image.png

执行 npm run test-live,会打开一个基于 Electron 真实的浏览器。

image.png

添加版本管理

这里和大部分人一样使用 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 标准提交提示。
  1. 安装commitlint和添加配置。
npm install @commitlint/config-conventional @commitlint/cli -D

修改package.json文件,添加如下配置。

  "commitlint": {
    "extends": [
      "@commitlint/config-conventional"
    ]
  },

这里使用的 config-conventional 规则,具体可以参考这里

  1. 安装lint-staged和添加配置。
npm i lint-staged -D

修改package.json文件。

  "lint-staged": {
    "*.js": ["npm run lint:fix"] 
  },

对暂存区的文件执行npm run lint:fix

  1. 初始化 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-commitcommit-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: 初始化" 规则

我正在参与掘金技术社区创作者签约计划招募活动,点击链接报名投稿