zoukankan      html  css  js  c++  java
  • 路径 alias 在 Node 中的最佳姿势

    想法

    我们来想想有没有其他解决方案,假定当前项目目录结构为

    ├── src
    |   ├── config
    |   └── controller
    ├── node_modules
    ├── index.js
    └── package.json

    1. 全局变量

    第一反应,在 Node 程序里面,我们可以直接通过

    global.BASE_PATH = __dirname + '/'

    之后就可以这么使用

    import config from BASE_PATH + 'src/config'

    emmmm,太丑了,而且也没方便到哪去,抬走

    2. symlink

    再一想,想起来在系统中有一个符号链接的东西,再利用 Node 的模块加载机制,我们可以在项目的 node_modules 下建一个链接到项目目录的符号链接。

    1. Linux / MacOS (其实就是 unix 内核的系统)

      ln -nsf node_modules src
    2. Windows

      mklink D src node_modules

    然后就可以这么使用

    import config from 'src/config'

    看起来不错,但是也有一些槽点

    • 不同平台创建命令不一致
    • 每个clone仓库的人都要手动添加符号链接

    既然有槽点,那就解决一下,印象中 Node 的 fs 模块提供了创建 symlink 的方法: fs.symlinkSync ,我们把具体代码写出来,第一个问题迎刃而解。

    const src='../src'
    const dir='node_modules/src'
    const fs = require('fs')
    fs.exists(dir, function (e) { e || fs.symlinkSync(src, dir, 'dir') })

    第二个问题就简单了,我们利用 package.json scripts 中的 postinstall 钩子,它会在 npm run install 之前被执行,我们把前面写好的代码浓缩一下放进去用 node 执行即可。

    {
      "scripts": {
        "postinstall": "node -e "var src='../src',dir='node_modules/src',fs=require('fs');fs.exists(dir,function(e){e||fs.symlinkSync(src,dir,'dir')});""
        }
    }

    到这里看起来就很不错了,不过仔细一想,还有个小问题。当我们想再加一个 alias,比如 @controller -> src/controller 的时候,喔霍,又得改 postinstall 脚本。

    更好一点的做法是将 postinstall 中的脚本抽出来保存成一个单独的文件,但是还是无法避免新增时要修改脚本的问题。

    我们可以再通过命令行参数来解决这个问题,但是需要引入新的命令,整个流程就比较繁琐了,新人接手可能还要花点时间才能搞懂这里的逻辑。

    3. 环境变量

    想了想,又想起来一个知识点,我们可以通过设置环境变量 NODE_PATH 指向对应的路径

    export NODE_PATH='项目路径'

    之后就可以直接使用

    import config from 'src/config'

    原理和Node模块加载机制有关,感兴趣的自行查阅,这里就不多说了。

    这个方案的缺点也很明显,没错, NODE_PATH 只有一个,因此生成的 alias 只有该路径下的最顶层,没办法添加 src/controller -> controller 这样的 alias。

    资源搜索网站大全 https://www.renrenfan.com.cn 广州VI设计公司https://www.houdianzi.com

    业界方案

    自己的思考大概结束了,我们来看看业界的实现方案。搜了一圈之后,聚焦在一个轮子上: module-alias

    看了下源码是通过 hack 原生模块 module 的方法实现的,Node在引入模块时其实就是调用的module 模块。具体源码就不多说了,我们直接来看最佳实践(我认为的)

    module-alias 提供了两种 alias 添加模式

    1. 配置package.json

      通过配置 _moduleAliases 字段添加 alias

      // package.json
      {
        "_moduleAliases": {
          "@src": "src",
          "@config": "src/config"
        }
      }
      // index.js
      import 'module-alias/register'
    2. 在项目代码中添加

      import { addAlias } from 'module-alias'
      
      addAlias('@root', __dirname)
      addAliases({
       '@src': __dirname + 'src',
       '@config': __dirname + 'src/config'
      })

    之后就可以使用配置的 alias 进行开发了,但是还有一个问题,我们在 VSCode 中的引用没办法点击跳转,引用的模块提示也不能正常加载。

    这是因为 VSCode 并不知道这个路径解析的配置,所以需要额外添加配置。只需要配置一下 jsconfig.json (使用 typescript 的修改 tsconfig.json )的 compilerOptions

    {
      "compilerOptions": {
        "moduleResolution": "node",
        "baseUrl": ".",
        "rootDir": ".",
        "paths": {
          "@config": ["src/config"],
          "@src/*": ["src/*"]
        }
      }
    }

    需要注意的是,jsconfig.json更改后需要重新打开 VSCode 配置才会生效

    以上配置完即可愉快的进行开发了,提高效率、治好强迫症的同时代码提示、引用跳转等都可以正常使用。

  • 相关阅读:
    Jmeter之Constant Timer与constant throughput timer的区别(转)
    JMeter Exception: java.net.BindException: Address already in use: connect(转)
    jmeter的jtl日志转html报告常见报错笔记
    jmeter 启动jmeter-server.bat远程调用报错: java.io.FileNotFoundException: rmi_keystore.jks (系统找不到指定的文件。)
    jmeter5.0生成html报告 快速入门
    图片转字符画 【学习ing】
    python生成个性二维码学习笔记
    Processing 3!
    Python Selenium定位元素常用解决办法
    js 获取元素坐标 和鼠标点击坐标
  • 原文地址:https://www.cnblogs.com/xiaonian8/p/14085223.html
Copyright © 2011-2022 走看看