内部前端工具平台搭建
这是什么?
- 前端组内部的脚本工具沉淀在这个地方,可以让组员很方便的共享和使用
- 我们希望能像执行linux命令一样去执行一些简洁命令,如:fe xx,然后能实现一些功能
想达到的效果?
- 类似 npm install -g eslint 后,终端输入eslint,就可以执行eslint的校验脚本
- 我们是执行 fe xx , 可以执行我们自己的脚本
先设计如何使用,后实现 (fe是font-end的缩写)
- 安装:npm install -g @myCompany/fe
- 使用: ```javascript 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模式
<a name="0ce29b70"></a>
## 如何搭建一个这样的前端工具平台呢?
先列大纲,下面会细讲
1. 用内部gitlab管理代码(没有的话,公网github或gitee也可以)
1. 需要内部npm域(没有的话,公网npm也可以)
- 作用:让小组其他成员可以方便下载(npm install -g xx),其次,可以很方便的管理版本
3. 配置package.json
3. 配置入口文件main.js
3. 发布到内部npm域
3. 开发脚本过程中的测试?
<a name="d73e355d"></a>
## 1. 用内部gitlab管理代码(没有的话,公网github或gitee也可以)
基本的git操作,相信大家都会,略过
<a name="d85e0874"></a>
## 2. 需要内部npm域(没有的话,公网npm也可以)
跟着下面第5点(5. 发布到内部npm域)一起讲
<a name="fe4f0b02"></a>
## 3. 配置package.json
```json
{
"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
// 上面是配置当前的环境变量地址: mac上是固定的
/* 文件说明:
* 命令的入口文件
*/
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. 开发脚本过程中的测试?
- 小脚本
- 可以直接copy文件到测试项目内,直接test
- 缺点:因为是手动copy的,所以写相对路径的话,可能不准,可以用path.resolve()解析成绝对路径
- 通用方法(不手动copy,就在源文件内)
- npm link : https://docs.npmjs.com/cli/v7/commands/npm-link
- 用编辑器拿到main.js绝对路径,然后就可以直接执行
例如: /Users/xxx/Desktop/project/xxx/bin/main.js (效果和执行 fe 一样)
需要打debugger的话:
在当前的项目内的根目录下,输入
node —inspect-brk bin/main.js,就可以启动调试模式