内部前端工具库搭建

1,328 阅读6分钟

内部前端工具库搭建

这是什么?

  • 前端组内部的脚本工具沉淀在这个地方,可以让组员很方便的共享和使用
  • 我们希望能像执行linux命令一样去执行一些简洁命令,如:fe xx,然后能实现一些功能

想达到的效果?

  • 类似 npm install -g eslint 后,终端输入eslint,就可以执行eslint的校验脚本
  • 我们是执行 fe xx , 可以执行我们自己的脚本

先设计如何使用,后实现 (fe是font-end的缩写)

  1. 安装:npm install -g @myCompany/fe
  2. 使用:
    fe  或  fe -h     查看帮助 
    fe -v             查看版本
    
    实际使用平台工具,举例:
    终端输入:fe 
    // 以下会打印
      cli              脚手架拉取内部模板
      mock             切换到mock模式.   根据fe.config.js内的apiAndMock对象
      api              正常模式: 从mock模式切换到api模式.   根据fe.config.js内的apiAndMock对象
      api-pkg          pkg模式: 切换到api模式, 且把响应的返回值在包一层, 简化输出.
                       根据fe.config.js内的apiAndMock对象
      route            根据fe.config.js内的route对象, 自动生成./route/routes.js 和 路由对应的
                       .vue文件(./src/components内),
      file-route       根据传入的参数监听目录(默认监听 components 目录),当文件发生变化时自动生成
                       ./route/routes.js 文件。(eg: fe file-route views 监听 views 目录)
      lan              中文提词及回填工具, 使用示例: fe lan ./src/views [replace或r] [noOutput或n]
      getEn            把 "中文": "English" 转成 "English": "English", 使用示例: fe getEn
                       src/langs/en.json
      -h, --help       display help for command
      
    终端输入:fe mock  
            会执行mock部分的脚本,切换到mock模式
    

如何搭建一个这样的前端工具库呢?

先列大纲,下面会细讲

  1. 用内部gitlab管理代码(没有的话,公网github或gitee也可以)
  2. 需要内部npm域(没有的话,公网npm也可以)
    • 作用:让小组其他成员可以方便下载(npm install -g xx),其次,可以很方便的管理版本
  3. 配置package.json
  4. 配置入口文件main.js
  5. 发布到内部npm域
  6. 开发脚本过程中的测试?

1. 用内部gitlab管理代码(没有的话,公网github或gitee也可以)

基本的git操作,相信大家都会,略过

2. 需要内部npm域(没有的话,公网npm也可以)

跟着下面第5点(5. 发布到内部npm域)一起讲

3. 配置package.json

文档 caibaojian.com/npm/files/p…

{
  "name": "@myCompany/fe",
  "version": "1.0.51",
  "description": "前端工具平台",
  "scripts": {
    "dev": "node bin/main.js",
    "p": "node utils/publish.js && lnpm publish && npm i -g @myCompany/fe"
  },
  "author": "bigtree",
  "license": "ISC",
  "dependencies": {
  
  },
  "devDependencies": {
    
  }"bin": { // 其他的字段,相信大家都比较熟悉, 此处最重要的要讲的是bin字段
    "fe": "./bin/main.js" // 注意此处的"./bin/main.js",指向了目录(文件目录结构在下方)内的main.js文件
  }
}

// 其他的字段,相信大家都比较熟悉, 此处最重要的要讲的是bin字段
- 为了要实现:终端输入:fe  能打印xxx 执行脚本,需要配置bin
    // 参考eslint的源码内的package.json
    "bin": {
        "eslint": "./bin/eslint.js" // bin的对象的key,能作为类似node一样,作为全局环境变量被解析。实际上也是node来触发
    },

文件的目录结构
    @myCompany-fe
        bin
            main.js
        .gitignore
        package.json
        package-lock.json
        README.md
// 终端执行效果 如下,fe会被加入node的全局变量池中
xxx-MacBook-Pro / % npm i -g @myCompany/fe
xxx-MacBook-Pro / % where fe
/Users/xxx/.nvm/versions/node/v12.21.0/bin/fe
xxx-MacBook-Pro bin % cd /Users/xxx/.nvm/versions/node/v12.21.0/bin
xxx-MacBook-Pro bin % ls
fe           eslint         http-server       node          npm      
npx          stylelint

安装: npm i -g @myCompany/fe (需发布,如何发布在第5点(5. 发布到内部npm域)还未讲 )

最终终端输入:fe, 就会执行 @myCompany-fe/bin/main.js

4. 配置入口文件main.js

#! /usr/bin/env node
// 上面是当前环境node的地址,正常安装的话就是这个

/* 文件说明:
 *   命令的入口文件
*/

const commander = require('commander') // 让命令生效, 如: fe -h
const Chalk = require('chalk')
const path = require('path')
const pkgJson = require('../package.json')
const { exec } = require('child_process') // 执行命令行 如: node a.js
const autoRouteAndFile = require('./autoRouteAndFile/entry.js') // 其他脚本文件
const autoApiAndMock = require('./autoApiAndMock/entry.js') // 其他脚本文件
const autoFileRoute = require('./autoFileRoute/entry.js') // 其他脚本文件

// 定义版本号以及命令选项
commander
  .version(pkgJson.version, '-v -V --version') // 不写后面这个的话,只能用大写的 -V
  .option('cli', '脚手架拉取内部模板')
  .option('mock', '切换到mock模式.   根据fe.config.js内的apiAndMock对象')
  .option('api', '正常模式: 从mock模式切换到api模式.   根据fe.config.js内的apiAndMock对象')
  .option('api-pkg', 'pkg模式: 切换到api模式, 且把响应的返回值在包一层, 简化输出.   根据fe.config.js内的apiAndMock对象')
  .option('route', '根据fe.config.js内的route对象, 自动生成./route/routes.js 和 路由对应的 .vue文件(./src/components内), ')
  .option('file-route', '根据传入的参数监听目录(默认监听 components 目录),当文件发生变化时自动生成 ./route/routes.js 文件。(eg: fe file-route views 监听 views 目录)')
  .option('lan', '中文提词及回填工具, 使用示例: fe lan ./src/views [replace或r] [noOutput或n]')
  .option('getEn', '把 "中文": "English" 转成 "English": "English", 使用示例: fe getEn src/langs/en.json')
  .parse(process.argv) // let commander can get process.argv

// 配置文件的绝对路径 (当前命令执行的路径)
const configPath = path.join(process.cwd(), 'fe.config.js')
console.log('读取配置文件的路径是: ' + configPath)

// get ./fe.config.js
const getConfig = (key) => {
  let Config = null
  try {
    Config = require(configPath)
  } catch (e) {
    console.log(Chalk.red('error: 使用此命令,必须先配置fe.config.js'))
    console.error(Chalk.red(e))
  }
  if (Object.prototype.toString.call(Config) === '[object Object]') {
    if (!key) {
      return Config
    } else {
      if (Config[key]) {
        console.log(Chalk.green('读取配置文件成功!'))
        return Config[key]
      } else {
        console.log(Chalk.red(`请配置fe.config.js里面的 ${key} 配置项`))
      }
    }
  } else {
    console.error(Chalk.red('请正确配置fe.config.js'))
  }
}

// main
const main = () => {
  if (commander.args.length === 0) { // 当直接输入fe 时
    const realPath = path.join(__dirname, 'main.js')
    exec(`node ${realPath} -h`, (err, stdout, stderr) => {
      if (err) console.error(Chalk.red(err))
      console.log(`欢迎使用前端工具平台, 使用示例: fe mock  \n${stdout}`)
    })
  } else { // 当输入fe xx 时
    const cmd = commander.args[0]
    if (['mock', 'api', 'api-pkg'].includes(cmd)) {
      autoApiAndMock(getConfig('apiAndMock'))
    } else if (cmd === 'route') {
      autoRouteAndFile(getConfig('route'))
    } else if (cmd === 'file-route') {
      autoFileRoute(getConfig('fileRoute'))
    } else if (cmd === 'lan') {
      require('./lan/lan-script.js')
      console.log('do something...')
    } else if (cmd === 'getEn') {
      require('./lan/getIndia.js')
    }
  }
}

main()

5. 发布到内部npm域

打开控制台,输入以下指令

  • 如果你是第一次发包,使用 npm adduser
  • 如果不是第一次发, 使用 npm login

紧接着出现,输入账号名字,密码,邮箱

username:xxx
password:
Email:xxx@xxx.com 

在项目的根目录下,与 package.json 同级的目录

  • 输入 npm publish , 发布

然后你就可以在 内部npm域或公网npm域 里面找到自己的刚刚发布的包了

6. 开发脚本过程中的测试?

  1. 小脚本

    • 可以直接copy文件到测试项目内,直接test
    • 缺点:因为是手动copy的,所以写相对路径的话,可能不准,可以用path.resolve()解析成绝对路径
  2. 通用方法(不手动copy,就在源文件内)

    1. npm link : docs.npmjs.com/cli/v7/comm…
    2. 用编辑器拿到main.js绝对路径,然后就可以直接执行 absolutePath.png

    例如: /Users/xxx/Desktop/project/xxx/bin/main.js (效果和执行 fe 一样)

需要打debugger的话:

在当前的项目内的根目录下,输入 node --inspect-brk bin/main.js,就可以启动调试模式


码字不易,点赞鼓励!