通常在 vue-cli 脚手架 src 目录下,有一个 api 文件夹,用来存放被抽离出的 API 请求,如下图所示:
其中 module 文件夹下存放各模块抽离的 API,axios.ts 文件创建 axios 的一个实例,并添加一些公共配置(如:baseURL, timeout,拦截器等),index.ts 即是向外暴露各种 API 方法。
module 下的每个文件内容格式基本都一样:
get 请求传参数有点不同:
export function getSome (
params?: any
): Promise<Ajax.AjaxResponse> {
return ax.get('/some', { params })
.then(res => res.data)
.catch(error => console.error(error))
}
复制代码
当项目越来越大,module 下的文件越来越多时(但文件内容基本一样),本着能少写代码就少写代码的我,冒出一个想法,是否能通过一个 json 文件,来生成所需要的文件?如下图:
定义一个如上 json 文件,执行一段脚本,它就可以生成包含下图代码文件:
我们的目的很简单,读取一个 json 文件,把 json 文件里对应字段的值,写入到一个 .ts 文件里。
这里,我们用到 node 的 fs 模块,用来读取与写入文件。
// index.js
const fs = require('fs')
// 读取 json 文件
const data = fs.readFileSync(`user.json`)
// parse 导入文件
const content = JSON.parse(data)
复制代码
定义每个函数的 template:
const template = item => {
return `// ${item.des}\n` +
`export function ${item.name} (params?: any)` +
`: Promise<Ajax.AjaxResponse> {\n` +
` return ax.${item.method}('${item.url}', ` +
`${item.method === 'get' ? '{ params }' : 'params'})\n` +
` .then(res => res.data)\n` +
` .catch(error => console.error)\n` +
`}\n\n`
}
复制代码
接着遍历 content
let result = "import ax from '../axios'\n\n"
content.forEach(item => {
result += template(item)
})
// 生成文件
fs.writeFileSync(`user.ts`, result)
复制代码
执行命令 node index.js
,发现这次尝试是成功的:
实际中,module 应该是很多个,而且输出文件的名字,应该是与对应 json 文件的名字是相同的。就像下图一样:
我们来改动一下前面所写的代码:
const fs = require('fs')
const path = require('path')
// 入口文件夹
const enPath = path.resolve(__dirname, '../src/ajax')
// 出口文件夹
const outPath = path.resolve(__dirname, '../src/api/module')
// 目录不存在时,创建
if (!fs.existsSync(outPath)) {
fs.mkdirSync(outPath)
}
const template = item => {
return `// ${item.des}\n` +
`export function ${item.name} (params?: any)` +
`: Promise<Ajax.AjaxResponse> {\n` +
` return ax.${item.method}('${item.url}', ` +
`${item.method === 'get' ? '{ params }' : 'params'})\n` +
` .then(res => res.data)\n` +
` .catch(error => console.error)\n` +
`}\n\n`
}
// 读取文件夹
const files = fs.readdirSync(enPath)
// 读取单个文件,生成所需文件
files.forEach(file => {
const data = fs.readFileSync(`${enPath}/${file}`)
const fileName = file.split('.')[0]
let result = ''
if (data.length) {
result = "import ax from '../axios'\n\n"
const content = JSON.parse(data)
content.forEach(item => {
result += template(item)
})
}
fs.writeFileSync(`${outPath}/${fileName}.ts`, result)
console.log(`写入文件成功:${outPath}/${fileName}.ts`)
})
复制代码
执行命令 node index.js
,自此,就基本达成了最初的目的。
实际过程中,可能并没什么卵用,比如说某些请求里,需要加不同的配置( baseURL, header 等),还有可能文件夹 ajax 下还细分了文件夹等。不过,折腾一下,总能出来。