今天目的是想写一个简单的 node 命令行,并能读取以 ts 文件书写的配置。方便大家定义配置时能有完整的类型提示。
思路是使用 @babel/register 实现,最初的代码如下:
// bin/auto.js 代码如下
require("@babel/register");
const path = require('path');
// 读取当前命令行运行目录下的 app.ts 文件
const config = require(path.resolve('./', 'app.ts'));
// 打印配置信息
console.log(config);
/* ------------------------ */
// app.ts 文件代码如下
interface a {
b: string;
}
export default {
a: 1
}
使用 node 命令行执行直接报错
node bin/auto.js
# 运行后直接报错
xxx/app.ts:2
export default {
^^^^^^
SyntaxError: Unexpected token 'export'
定位是识别不了 ts 语法,在网络上找了各种文章,花了将近 1 小时都没有解决问题。最后才去官网学习理解 @babel-register 的原理。
@babel-register 实际上为 require 加了一个钩子(hook),在 require(“@babel/register”) 执行之后所有被 node 引用的 .es6、.es、.jsx 以及 .js 文件都会先被 Babel 转码。
进一步思考,为什么没有转码 ts ,是因为 ts 不默认支持的文件类型,那么我们是否可以手动去添加。进一步看使用文档,最后发现了 extensions 配置项。修改代码,最终如下
require("@babel/register")({
presets: [ "@babel/preset-env", '@babel/preset-typescript'],
// 添加 .ts 文件
extensions: [".es6", ".es", ".jsx", ".js", ".mjs", ".ts"],
// Setting this to false will disable the cache.
cache: true,
});
const path = require('path');
const config = require(path.resolve('./', 'app'))
console.log(config);
我发现在使用一个新技术的时候,自己首先想着的是如何快速达成目的,从而去找各种快捷简单的方案。
到最后,我如静下心来,先学习这个技术的原理与基本的用法,这样反而效率更高,而且我在后续引用这些技术的自信心更充足了。
想起了以前自己分享的文章
我真的把我分享的应用到实践中了吗?今天就没有,明天呢?
记住,不要一直想着怎么解决难题,而是先把难题彻底搞明白先。