likes
comments
collection
share

如何快速评估改动代码的影响范围

作者站长头像
站长
· 阅读数 10

背景

改动代码时, 了解改动代码的影响范围是一个非常好的编程习惯

假设你要改动项目里的一个组件, 请问你知道哪些地方会受到影响吗? 即要找出哪些地方用到了这个组件.

下面以 Vue 单文件开发模式, 借助 vscode(1.81.1) 编辑器为你演示具体如何操作

结论

  • 改动导入的模块时, 通过 Find All References 以评估影响范围

    如何快速评估改动代码的影响范围

    注意: 此方法仅适用于导入的模块为 .js/.ts/.vue

  • 改动变量时, 通过传统的搜索以评估影响范围

具体场景

改动导入的模块

应对的场景: 在代码中导入了一个的组件或者方法, 我需要改一下这个组件或者方法, 想知道在项目范围内还有哪些地方用到了, 以评估影响范围. 特别是在做一些不兼容的改动时, 避免出现改动 A 却影响了 B 还不知情的情况.

例如:

// 我需要改动导入的 HelloWorld 这个组件
import HelloWorld from '../components/HelloWorld.vue'

针对这种场景, 我们的第一反应可能是直接项目范围内搜索不就可以了吗?

但实际情况没这么简单, 因为导入模块的方式可能多种多样, 这会导致项目范围内搜索可能找不全

  • 路径可能不相同

    导入的路径可能是相对路径, 也可能是绝对路径(通过别名)

    // 相对路径
    import HelloWorld from '../components/HelloWorld.vue'
    // 绝对路径
    import HelloWorld from '@/components/HelloWorld.vue'
    

    还可能省略文件扩展名

    import util from '../util/index.js'
    import util from '../util/index'
    

    甚至省略到只有文件夹

    import util from '../util' //  '../util' === '../util/index.js'
    
  • 导入的名字可能不相同

    针对默认导出, 导入的时候, 名字是可以随便取的

    import HelloWorld from '../components/HelloWorld.vue'
    import HelloWorld123 from '../components/HelloWorld.vue'
    

而且项目范围内搜索可能找到很多相同名字的导入, 会加大我们排查的工作量.

要应对这种场景, 我们可以使用 vscode 提供的 Find All References 功能, 快速找到项目范围内还有哪些地方也导入了相同的模块

根据路径去找

例如:

import util from '../util/index.js'

适用于导入了默认导出的模块, 找出哪些地方导入了相同的模块(文件)

具体操作方式如下

  1. 在导入模块路径处单击鼠标右键
  2. 从右键菜单中选择"Find All References"
  3. 左侧"References"面板中的结果即项目范围内所有用到了该模块的地方

根据命名去找

例如:

import {
  VERSION,
} from '../util/constant.js'

适用于导入了命名导出的模块, 找出哪些地方导入了相同模块的命名

如何快速评估改动代码的影响范围

具体操作方式略有不同

  1. 在导入命名处单击鼠标右键

  2. 从右键菜单中选择"Find All References"

  3. 左侧"References"面板中的结果即我们想要的

    还为你找到了定义该导出的位置

注意: 针对导入了默认导出的模块, 一定要使用根据路径去找的方式去操作, 不然会找不全

例如

import testUtil from '../util/index.js'
import test from '../util/index.js'

如果只找 testUtil 的话, 就只会找到当前文件中引用的 testUtil

识别别名路径

为了导入更加方便, 以及提升构建性能, 我们会使用例如 webpack 提供的 alias 能力, 让我们支持使用别名路径来导入模块

默认情况下, vscode 识别不了别名路径的导入, 因此 References 的结果中缺少别名路径导入的模块.

需要根据你配置的 alias 来额外配置 jsconfig.json(放置在项目根目录)的 compilerOptions.paths 才能识别

具体配置方式如下, 以常用的 @ 别名为例

{
    "compilerOptions": {
        "baseUrl": ".",
        "paths": {
            "@/*": ["./src/*"]
        }
    }
}

注意: 新增该配置或者改动该配置, 需要重启一下 vscode 才会生效

重启后再执行 Find All References 就可以找到使用了别名的导入了, 别名路径也支持 Go to Definition

改动变量

应对的场景: 我需要改动代码中的一个变量, 想知道在项目范围内还有哪些地方用到了, 以评估影响范围. 特别是在做清理工作时, 避免出现遗漏.

例如:

export default {
  data() {
    return {
      // 我需要删除掉 hello 这个字段
      hello: 'vue'
    };
  }
}

尝试使用 Find All References 也可以找到一些引用, 但是不全, 其中

  • 缺失模版中的引用(在视图中使用了)
  • 很多场景都没有覆盖到

为了确保找到全部的引用, 使用传统的搜索功能去查找才更稳妥

  • 如果评估为局部变量, 只需要在文件范围内查找即可

    例如方法中的局部变量

    methods: {
      doSomething() {
        // 要删除 test 局部变量, 只需要在文件范围内查找即可找到所有的影响范围
        // 如果是使用 TS 的话, 可以直接删除该局部变量, 编译器会直接报错告诉你哪里用到了
        let test = 1
        console.log(test)
      }
    }
    
  • 如果评估为非局部变量, 建议先在文件范围内查找, 再扩大范围在项目范围内查找

    例如 methods 中定义的方法

    methods: {
      // 要删除 doSomething 这个方法
      // 因为可能存在外部引用了组件调用组件方法的情况
      // 稳妥起见, 我们先在文件范围内查找, 找到当前文件内的使用情况, 将之删除
      // 再扩大范围在项目范围内查找, 排查可能存在的外部调用情况, 将之删除
      //
      // 为了减少项目范围内排查耗费时间
      // vue2 建议约定仅非下划线开头的才暴露给外部调用
      // vue3 建议使用 expose 声明当组件实例被父组件通过模板引用访问时暴露的公共属性
      // https://cn.vuejs.org/api/options-state.html#expose
      doSomething() {
        let test = 1
        console.log(test)
      }
    }
    

总结

在改动代码之前, 通过 Find All References 和搜索, 可以让我们明确改动的影响范围, 大大减少因评估不到位而产生的线上问题.