一. 课程目标
- 本次课程我们结合之前学过的命令行和网络模块来实现一个命令行翻译工具
二. 初始化
- 先新建文件夹,我这里命名为
node-translation
,然后做初始化项并修改版本号0.0.1
js
yarn init -y
- 初始化git,用来作为版本控制
git init
,并且添加.gitignore
bash
# 忽略依赖模块目录
node_modules/
# 忽略本地构建/临时文件目录
build/
temp/
dist/
# 忽略配置文件
config.js
config.json
# 忽略编辑器生成的文件和目录
.vscode/
.idea/
*.swp
# 忽略日志文件
logs/
*.log
# 忽略敏感信息(例如,API 密钥)
.env
# 忽略自动生成的文档
doc/
docs/
*.html
*.pdf
# 忽略特定文件
file-to-ignore.txt
# 忽略特定目录及其内容
directory-to-ignore/
# 忽略 Mac OS X 上的隐藏文件
.DS_Store
# 忽略 Windows 上的 Thumbs.db 文件
Thumbs.db
- 创建src存放源代码,并新建main.ts,命令行
ts-node-dev src/main.ts
能成功运行
js
console.log('test')
- 在package.json创建快速启动,之后直接运行
yarn start即可
ts
"scripts": {
"start": "ts-node-dev src/main.ts"
}
-
安装commander.js
yarn add commander@3.0.2
-
右键新建cli.ts用于处理命令行,
ts
#! /usr/bin/env node
import * as commander from 'commander';
import { translate } from './main';
const program = new commander.Command()
program.version('0.0.1')
.name('fy')
.usage('<English>')
.arguments('<English>')
.action(function (english) {
translate(english)
})
// 通过 program.parse(process.argv); 来解析实际的命令行参数,process.argv 包含了 Node.js 进程的命令行参数。
program.parse(process.argv);
- 新建main.ts写上翻译的逻辑
ts
import * as querystring from 'querystring';
import * as https from 'https';
const crypto = require('crypto');
export const translate = (word) => {
// 请求参数
const appId = '???';
const appSecret = '???';
const query = word;
const fromLanguage = 'en';
const toLanguage = 'zh';
const salt = Math.random();
// 计算签名(MD5加密)
const sign = crypto.createHash('md5').update(appId + query + salt + appSecret).digest('hex');
// 构建请求参数
const params = {
q: query,
from: fromLanguage,
to: toLanguage,
appid: appId,
salt: salt,
sign: sign
};
// 将请求参数编码成查询字符串
const queryString = querystring.stringify(params);
// 构建请求选项
const options = {
hostname: 'api.fanyi.baidu.com',
path: '/api/trans/vip/translate?' + queryString,
method: 'GET'
};
// 发送请求
const req = https.request(options, (res) => {
let data = '';
res.on('data', (chunk) => {
data += chunk;
});
res.on('end', () => {
console.log(data);
});
});
req.on('error', (error) => {
console.error('请求出错: ' + error.message);
});
req.end();
}
五. 如何处理appId和Secret
- 一般来说,创建一个文件叫做private.ts,并在git中忽略
ts
// private.ts导出
export const appId = '20200426000430230';
export const appSecret = 'N8pi1gg86hxPLIdvh7n0';
// main.ts中引入
import { appId, appSecret } from './private';
- 将简写的res,req写全,并且将获得的翻译数据转成json
ts
// 发送请求
const request = https.request(options, (response) => {
let data = '';
response.on('data', (chunk) => {
data += chunk;
});
response.on('end', () => {
console.log(data);
const object = JSON.parse(data)
console.log(object)
});
});
request.on('error', (error) => {
console.error('请求出错: ' + error.message);
});
request.end();
- 根据文档给object定义类型,并且打印出翻译
ts
type BaiduResult = {
error_code?: string;
error_meg?: string;
from: string;
to: string;
trans_result: { src: string; dst: string; }[]
}
response.on('end', () => {
console.log(data);
const object: BaiduResult = JSON.parse(data)
console.log(object)
console.log(object.trans_result[0].dst);
});
六. 继续完善功能
- 加上处理错误的逻辑和退出进程代码
ts
response.on('end', () => {
const object: BaiduResult = JSON.parse(data)
if(object.error_code) {
console.error(object.error_msg)
process.exit(1)
} else {
console.log(object.trans_result[0].dst);
process.exit(0)
}
});
- 增加中译英功能,通过正则实现
ts
let fromLanguage, toLanguage
if(/[a-zA-Z]/.test(word[0])) {
fromLanguage = 'en';
toLanguage = 'zh';
} else {
fromLanguage = 'zh';
toLanguage = 'en';
}
七. 开始准备发布
- 确定命令行,package.json中添加命令,但是这个时ts文件,只能通过ts-node-dev来运行
- 我们需要把ts编译成js
json
"bin": {
"fy": "src/cli.ts"
},
- 通过tsc编译把ts项目编程js
- 先运行
tsc --init
,会多一个tsconfig.json文件,然后修改此文件
- 先运行
csharp
tsc --init
- 把代码放到dest目录
json
"outDir": "dist/"
-
需要注意不能直接运行tsc,需要运行
tsc -p .
,把当前目录当成一个项目 -
给cli.ts加一个shebang,指明编译后的文件需要用nodejs来运行
js
#! /usr/bin/env node
- 在package.json中写明需要发布的文件
json
"main": "dist/main.js",
"bin": {
"fy": "dist/cli.js"
},
"files": [
"dist/**/*.js"
],
- 开始上传
perl
nrm use taobao
npm addUser
npm publish
- 上传之后安装一下看一下是否能够使用
八. 对比一下其它优秀的案例
- 参考一下,自己可以完善一些其它功能
csharp
yarn global add fanyi
fanyi apple
fanyi 键盘
// 如果不行的话 尝试运行npx fanyi apple