今天目的是想写一个简单的 node 命令行,并能读取以 ts 文件书写的配置。方便大家定义配置时能有完整的类型提示。

    思路是使用 @babel/register 实现,最初的代码如下:

    1. // bin/auto.js 代码如下
    2. require("@babel/register");
    3. const path = require('path');
    4. // 读取当前命令行运行目录下的 app.ts 文件
    5. const config = require(path.resolve('./', 'app.ts'));
    6. // 打印配置信息
    7. console.log(config);
    8. /* ------------------------ */
    9. // app.ts 文件代码如下
    10. interface a {
    11. b: string;
    12. }
    13. export default {
    14. a: 1
    15. }

    使用 node 命令行执行直接报错

    1. node bin/auto.js
    2. # 运行后直接报错
    3. xxx/app.ts:2
    4. export default {
    5. ^^^^^^
    6. SyntaxError: Unexpected token 'export'

    定位是识别不了 ts 语法,在网络上找了各种文章,花了将近 1 小时都没有解决问题。最后才去官网学习理解 @babel-register 的原理。

    @babel-register 实际上为 require 加了一个钩子(hook),在 require(“@babel/register”) 执行之后所有被 node 引用的 .es6、.es、.jsx 以及 .js 文件都会先被 Babel 转码。

    进一步思考,为什么没有转码 ts ,是因为 ts 不默认支持的文件类型,那么我们是否可以手动去添加。进一步看使用文档,最后发现了 extensions 配置项。修改代码,最终如下

    1. require("@babel/register")({
    2. presets: [ "@babel/preset-env", '@babel/preset-typescript'],
    3. // 添加 .ts 文件
    4. extensions: [".es6", ".es", ".jsx", ".js", ".mjs", ".ts"],
    5. // Setting this to false will disable the cache.
    6. cache: true,
    7. });
    8. const path = require('path');
    9. const config = require(path.resolve('./', 'app'))
    10. console.log(config);

    我发现在使用一个新技术的时候,自己首先想着的是如何快速达成目的,从而去找各种快捷简单的方案。

    到最后,我如静下心来,先学习这个技术的原理与基本的用法,这样反而效率更高,而且我在后续引用这些技术的自信心更充足了。

    想起了以前自己分享的文章

    04.04.七.把难题彻底搞明白,难题就解决了一半 📚

    我真的把我分享的应用到实践中了吗?今天就没有,明天呢?

    记住,不要一直想着怎么解决难题,而是先把难题彻底搞明白先。