前言
公司的老项目部分import
是用的相对路径,之前写需求的时候也改过一部分,但是文件太多了,一个一个改显然不是长久之计,昨天突发奇想能不能用eslint --fix
来做下自动修复呢?于是,花了大概一个多小时写了一个plugin
来满足需求。
效果
昨天下午我写完之后,晚上回家在github上,找到了一个库github.com/steelsojka/...
这个库也能实现相同的效果,而且做的挺完善,不足之处在于不支持动态引入,比如这种
js
import('../../test.js')
作者也不维护了,于是我就自己补了一下处理动态引入的逻辑。
效果图如下:
思路
获取处理文件的路径
要想实现相对路径的修改,首先要拿到处理文件的绝对路径,这个我们可以 context.getFilename()
或者 context.filename()
获取
它的值类似于 /Users/chouchouji/alias-manager/src/aliases.ts
。
处理相对路径
然后就是获取 from
后面或者 import
里面的相对路径,eslint
是通过 ast
来实现代码内容解析的,我们要处理两种形式的 import
,
转化相对路径为绝对路径
这个就比较简单了,可以借助 node:path
来处理。
先通过 path.dirname
获取当前文件的上一级目录,通过 path.resolve
获取引入文件的绝对路径,然后根据需求出路路径,如果想把 src
替换为 @
,就切割获取绝对路径 src
后面的内容,用 replace
方法做替换就行
实践
可以通过 --rulesdir
这个参数来实现本地调试,
rules
是我新创建的目录,下面有我写的 eslint rule
的代码,
然后在你的 eslint
配置文件中加下该 rule
在 package.json
中加一个命令
js
"test:lint": "eslint --rulesdir ./rules \"src/**/*.{js,vue}\" --fix"
最后控制台执行 pnpm test:lint
就可以了
源码
js
## use-alias.js
const path = require('path');
module.exports = {
meta: {
name: 'eslint-plugin-alias',
type: 'problem',
docs: {
description: 'Use Alias',
},
messages: {
error: 'Use Alias',
},
fixable: 'code',
},
create: function (context) {
const filename = context.getFilename();
return {
ImportDeclaration(node) {
if (node.source.value.startsWith('.')) {
context.report({
node,
messageId: 'error',
fix: function (fixer) {
const absolutePath = path.resolve(
path.dirname(filename),
node.source.value,
);
const relativePath = 'src' + absolutePath.split('/src')[1];
return fixer.replaceText(
node.source,
`'${relativePath.replace('src', '@')}'`,
);
},
});
}
},
ImportExpression(node) {
if (node.source.value.startsWith('.')) {
context.report({
node,
messageId: 'error',
fix: function (fixer) {
const absolutePath = path.resolve(
path.dirname(filename),
node.source.value,
);
const relativePath = 'src' + absolutePath.split('/src')[1];
return fixer.replaceText(
node.source,
`'${relativePath.replace('src', '@')}'`,
);
},
});
}
},
};
},
};
结尾
如有疑问,欢迎留言