百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术文章 > 正文

开发一个辅助业务的命令行工具(辅助脚本开发)

wxin55 2024-10-25 18:05 13 浏览 0 评论


本文记录了搭建基于 TypeScript 的 Nodejs 命令行开发环境的全过程。

为何使用TypeScript


首先,对于编写类库或者工具而言,使用 TypeScript 的最大好处就是其提供了类型机制,可以避免我们犯一些低级错误。

其次,配合编辑器(如 VS Code),TypeScript 能提供强大的代码提示功能,我们不需要记忆很多API的具体使用,在编写代码时编辑器会自动进行提示。比如引入了 http 之后,输入 http. 就会提示可以使用的各个方法和属性,并给出详细的说明。

同是微软旗下,VS Code 具有非常强大便利的功能,强烈推荐使用 VS Code 进行 TypeScript 和 Nodejs 开发。

最后,使用 TypeScript 是大势所趋,很多大公司都在推 TypeScript,使用 TypeScript 开发,可以让我们对 TS 使用更加熟练。


初始化工程


建立命令行工具,需要先创建一个 npm 包。下文将使用 npm 工具来完成包的初始化和依赖的安装。

首先创建一个文件夹,然后运行初始化命令:


mkdir ts-node-demo && cd ts-node-demonpm init


控制台会出现一系列提示, 按照需求输入即可,然后一路回车,完成之后输入 yes 。


package name: (typescript-cli) version: (1.0.0) description: a cli in typescriptentry point: (index.js) test command: git repository: keywords: CLI,TypeScriptauthor: YourNamelicense: (ISC) MIT


初始化之后本地文件夹会出现一个 package.json 文件。我们的 npm 包就已经初始化完成了。为了避免误发布,我们在 package.json 中做一个更改:


- private: false,+ private: true,

初始化 Git


在当前目录下运行:


git init


然后在当前目录创建 .gitignore 文件,指定忽略 node_modules 文件夹:


node_modules/lib/

引入 Node 类型


既然是开发 Nodejs 程序,为了获得合适的类型校验和代码提示,我们需要引入 Nodejs 的类型文件:


npm i -D @types/node

引入 typescript

npm i typescript


然后需要初始化 tsconfig 文件。


./node_modules/.bin/tsc --init


上述命令会在当前文件夹下面创建一个 tsconfig 文件,用来指导 TypeScript 进行编译。在里面有非常多的配置项,并且有非常详细的解释,我们做两个更改来适配我们的项目:


+ "sourceMap": true,+ "outDir": "lib",


上述配置指定生成 sourceMap 文件,并将 TypeScript 的编译结果输出到 ./lib 文件夹.

然后在与 compilerOptions 平级的地方增加选项:


"compilerOptions": {    ...},+ "include": [+    "src/**/*"+ ]


这表示我们只会编译 src 目录下的 .ts 文件。


编写代码


在当前目录下创建 src 文件夹,并创建 index.ts:


mkdir src && echo "console.log('Your cli is running.');" > src/index.ts


然后运行:


./node_modules/.bin/tsc


可以发现在文件夹下出现了 lib/ 目录,里面就是 index.ts 编译之后的 js 文件。


创建运行脚本


每次编译都需要引用 node_modules 里面的 tsc 命令,有些繁琐,有三种方法可以解决:

全局安装 typescript 包:


npm i typescript -g


就可以直接使用 tsc 命令了。

使用 npx 执行 npx 是 npm 提供的命令,其会自动下载对应的包并执行.


npx tsc


创建 npm 脚本 在 package.json 中的 script 中增加一行脚本:


"script": {+    "build": "tsc"}


这里我们采用第3种方法,写入脚本后可以执行:


npm run build


也会成功进行编译。


注册命令


开发 Nodejs 命令行工具,就是提供一个可以直接调用的命令,而不是使用下面这种方式执行文件:


node lib/index.js


我们想要的效果是执行一个命令就能调用我们的 js 文件。

首先在当前文件夹创建文件 bin/node-cli-demo :


mkdir bin && touch bin/node-cli-demo.js


然后在文件中写入以下内容:


#!/usr/bin/env noderequire('../lib/index.js');


npm 包注册的命令需要在 package.json 中进行声明,增加如下内容:


{    "name": "typescript-cli",    "version": "0.0.1",+   "bin": {+       "node-cli-demo": "./bin/node-cli-demo.js"+   },}


这表示当执行 node-cli-demo 这个命令时就去执行我们的 ./bin/node-cli-demo.js 文件。

最后在当前目录调用 npm link ,这条命令会把我们本地注册的命令放到 Nodejs 安装目录的 bin 文件夹下。在安装 Nodejs 时系统将该文件夹添加到命令查找的路径中。所以我们就可以直接使用我们刚刚注册的命令:


node-cli-demo// Your cli is running.

自动监听文件变动


我们希望每次更改了 .ts 文件之后,不必手动执行 npm run build 就能看到最新的效果,可以使用 typescript 的 --watch 选项,在 package.json 中的 script 中增加 start 命令:


{    "script": {+       "start": "tsc --watch"    }}


在当前目录下运行命令:


npm start


然后对 src/index.ts 文件做一些更改,另开一个控制台窗口,运行 node-cli-demo,会发现打印的内容已经更新了。这样我们在开发时就只需要关注代码编写,而不用考虑编译的问题了。

接下来我们就可以在 src 文件里面写我们的具体代码了!

注: 本文的 demo 代码可以在 github 上查看。为了避免创建很多仓库,我将其放到了一个仓库的子目录里面。


总结


使用 TypeScript 开发 Nodejs 命令行的流程如下:

安装 typescript 并进行配置;

在 package.json 中声明命令并使用 npm link 将其链接到全局命令中;

使用 tsc --watch 自动监听文件变动并重新编译;

运行注册过的命令,查看效果。


配置ESLint


使用 ESLint 校验我们的代码,可以避免一些低级错误。而 TypeScript 现在推荐采用 ESLint 来检查代码。我们可以为我们的工程配置 ESLint。


安装依赖


首先安装依赖:


npm i -D eslint @typescript-eslint/parser  @typescript-eslint/eslint-plugin


@typescript-eslint/parser 是用来解析 TypeScript 代码的,类似于 @babel/parser;

@typescript-eslint/eslint-plugin 是 ESLint 插件,用来配置具体的检查规则。


设置配置


在根目录下创建 .eslintrc, 写入以下内容:


{    "root": true,    "parser": "@typescript-eslint/parser",    "plugins": [        "@typescript-eslint"    ],    "extends": [        "eslint:recommended",        "plugin:@typescript-eslint/eslint-recommended",        "plugin:@typescript-eslint/recommended"    ],    "rules": {        "no-console": "error"    },    // set eslint env    "env": {        "node": true    }}


root: true 表示当前目录就是寻找 ESLint 的最终配置,这样 ESLint 就不会再往上层寻找配置;

parse 指定了使用 @typescript-eslint/parser 来解析我们的 TypeScript 代码;

plugins 指定使用的 ESLint 插件;

extends 指定了额外使用的规则配置。插件指定了一系列自定义的规则配置,只有在 extends 中指定才会生效。

rules 中可以扩展我们自己的规则。

env 中可以指定我们代码运行的环境,这样就可以自动判断某些代码是不是有错误。比如上述配置了 node: true ,我们在使用 require 的时候就不会报错了。


运行校验命令


在 package.json 的 script 中写入:


{    "script": {        "lint": "eslint ./src --ext .ts"    }}


上述命令指定了对 ./src 目录下扩展名为 .ts 的文件进行校验。

然后运行 npm run lint,会发现控制台出现报错,我们的 ESLint 已经生效了。

配置 VSCode 的 ESLint 插件,编辑器在开发时就会自动提示有问题的代码,帮助我们编写符合规范的代码。


忽略某些文件


我们可以指定某些目录下的文件不进行校验,在当前目录下创建 .eslintignore ,类似 .gitignore,然后在里面写入需要忽略的目录或文件:


node_modules


至此,ESLint 也配置完成了!

以上就是搭建 Nodejs 命令行的 TypeScript 开发环境的全部内容了,希望能帮到大家~

相关推荐

ES6中 Promise的使用场景?(es6promise用法例子)

一、介绍Promise,译为承诺,是异步编程的一种解决方案,比传统的解决方案(回调函数)更加合理和更加强大在以往我们如果处理多层异步操作,我们往往会像下面那样编写我们的代码doSomething(f...

JavaScript 对 Promise 并发的处理方法

Promise对象代表一个未来的值,它有三种状态:pending待定,这是Promise的初始状态,它可能成功,也可能失败,前途未卜fulfilled已完成,这是一种成功的状态,此时可以获取...

Promise的九大方法(promise的实例方法)

1、promise.resolv静态方法Promise.resolve(value)可以认为是newPromise方法的语法糖,比如Promise.resolve(42)可以认为是以下代码的语...

360前端一面~面试题解析(360前端开发面试题)

1.组件库按需加载怎么做的,具体打包配了什么-按需加载实现:借助打包工具(如Webpack的require.context或ES模块动态导入),在使用组件时才引入对应的代码。例如在V...

前端面试-Promise 的 finally 怎么实现的?如何在工作中使用?

Promise的finally方法是一个非常有用的工具,它无论Promise是成功(fulfilled)还是失败(rejected)都会执行,且不改变Promise的最终结果。它的实现原...

最简单手写Promise,30行代码理解Promise核心原理和发布订阅模式

看了全网手写Promise的,大部分对于新手还是比较难理解的,其中几个比较难的点:状态还未改变时通过发布订阅模式去收集事件实例化的时候通过调用构造函数里传出来的方法去修改类里面的状态,这个叫Re...

前端分享-Promise可以中途取消啦(promise可以取消吗)

传统Promise就像一台需要手动组装的设备,每次使用都要重新接线。而Promise.withResolvers的出现,相当于给开发者发了一个智能遥控器,可以随时随地控制异步操作。它解决了三大...

手写 Promise(手写输入法 中文)

前言都2020年了,Promise大家肯定都在用了,但是估计很多人对其原理还是一知半解,今天就让我们一起实现一个符合PromiseA+规范的Promise。附PromiseA+规范地址...

什么是 Promise.allSettled()!新手老手都要会?

Promise.allSettled()方法返回一个在所有给定的promise都已经fulfilled或rejected后的promise,并带有一个对象数组,每个对象表示对应的pr...

前端面试-关于Promise解析与高频面试题示范

Promise是啥,直接上图:Promise就是处理异步函数的API,它可以包裹一个异步函数,在异步函数完成时抛出完成状态,让代码结束远古时无限回掉的窘境。配合async/await语法糖,可...

宇宙厂:为什么前端离不开 Promise.withResolvers() ?

大家好,很高兴又见面了,我是"高级前端进阶",由我带着大家一起关注前端前沿、深入前端底层技术,大家一起进步,也欢迎大家关注、点赞、收藏、转发。1.为什么需要Promise.with...

Promise 新增了一个超实用的 API!

在JavaScript的世界里,Promise一直是处理异步操作的神器。而现在,随着ES2025的发布,Promise又迎来了一个超实用的新成员——Promise.try()!这个新方法简...

一次搞懂 Promise 异步处理(promise 异步顺序执行)

PromisePromise就像这个词的表面意识一样,表示一种承诺、许诺,会在后面给出一个结果,成功或者失败。现在已经成为了主流的异步编程的操作方式,写进了标准里面。状态Promise有且仅有...

Promise 核心机制详解(promise机制的实现原理)

一、Promise的核心状态机Promise本质上是一个状态机,其行为由内部状态严格管控。每个Promise实例在创建时处于Pending(等待)状态,此时异步操作尚未完成。当异步操作成功...

javascript——Promise(js实现promise)

1.PromiseES6开始支持,Promise对象用于一个异步操作的最终完成(包括成功和失败)及结果值的表示。简单说就是处理异步请求的。之所以叫Promise,就是我承诺,如果成功则怎么处理,失败怎...

取消回复欢迎 发表评论: