Skip to content

Commit 85e14ce

Browse files
committed
fix: fix remove extraneous import implementation
1 parent 1843c63 commit 85e14ce

File tree

5 files changed

+65
-49
lines changed

5 files changed

+65
-49
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import Vue from 'vue'
22
import VueRouter from 'vue-router'
3-
import Vuex from 'Vuex'
3+
import Vuex from 'vuex'
44

55
Vue.use(VueRouter)
66
Vue.use(Vuex)
Original file line numberDiff line numberDiff line change
@@ -1,3 +0,0 @@
1-
import 'vue';
2-
import 'vue-router';
3-
import 'Vuex';

generator/codemods/global-api/remove-trivial-root.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
* It is expected to be run after the `createApp` transformataion
33
* if a root component is trivial, that is, it contains only one simple prop,
44
* like `{ render: h => h(App) }`, then just use the `App` variable
5-
*
5+
*
66
* TODO: implement `remove-trivial-render`,
77
* move all other rootProps to the second argument of `createApp`
88
* @param {Object} context

generator/codemods/router/index.js

+3-1
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,9 @@ module.exports = function(fileInfo, api) {
3939
} else if (mode === 'abstract') {
4040
initializer = 'createMemoryHistory'
4141
} else {
42-
console.error(`mode must be one of 'hash', 'history', or 'abstract'`)
42+
console.error(
43+
`mode must be one of 'hash', 'history', or 'abstract'`
44+
)
4345
return p
4446
}
4547

generator/codemods/utils/remove-extraneous-import.js

+60-43
Original file line numberDiff line numberDiff line change
@@ -2,61 +2,78 @@
22
* Note:
33
* here we don't completely remove the import declaration statement
44
* if all import specifiers are removed.
5-
* For example, `import Vue from 'vue'`,
6-
* if `Vue` is unused, the statement would become `import 'vue'`.
5+
* For example, `import foo from 'bar'`,
6+
* if `foo` is unused, the statement would become `import 'bar'`.
77
* It is because we are not sure if the module contains any side effects.
88
* @param {Object} context
99
* @param {import('jscodeshift').JSCodeshift} context.j
1010
* @param {ReturnType<import('jscodeshift').Core>} context.root
1111
*/
1212
module.exports = function removeExtraneousImport({ root, j }, name) {
13-
const isPathEqual = (path1, path2) => {
14-
return (
15-
path1.node.start === path2.node.start && path1.node.end === path2.node.end
16-
)
17-
}
18-
/**
19-
* @param {import('jscodeshift').ASTPath} path
20-
*/
21-
function filterAndRemoveImports(path) {
22-
const usages = j(path)
23-
.closestScope()
24-
.find(j.Identifier, { name })
25-
// Ignore the specifier
26-
.filter(identifierPath => {
27-
const parent = identifierPath.parent.node
28-
return (
29-
!j.ImportDefaultSpecifier.check(parent) &&
30-
!j.ImportSpecifier.check(parent)
31-
)
32-
})
33-
// Ignore properties in MemberExpressions
34-
.filter(identifierPath => {
35-
const parent = identifierPath.parent.node
36-
return !(
37-
j.MemberExpression.check(parent) &&
38-
parent.property === identifierPath.node
39-
)
40-
})
13+
const usages = root.find(j.Identifier, { name }).filter(identifierPath => {
14+
const parent = identifierPath.parent.node
4115

42-
if (!usages.length) {
43-
j(path).remove()
16+
// Ignore the import specifier
17+
if (
18+
j.ImportDefaultSpecifier.check(parent) ||
19+
j.ImportSpecifier.check(parent)
20+
) {
21+
return false
4422
}
45-
}
4623

47-
root
48-
.find(j.ImportSpecifier, {
49-
local: {
50-
name
51-
}
52-
})
53-
.filter(filterAndRemoveImports)
24+
// Ignore properties in MemberExpressions
25+
if (
26+
j.MemberExpression.check(parent) &&
27+
parent.property === identifierPath.node
28+
) {
29+
return false
30+
}
31+
32+
// Ignore keys in ObjectProperties
33+
if (
34+
j.ObjectProperty.check(parent) &&
35+
parent.key === identifierPath.node &&
36+
parent.value !== identifierPath.node
37+
) {
38+
return false
39+
}
40+
41+
return true
42+
})
5443

55-
root
56-
.find(j.ImportDefaultSpecifier, {
44+
if (!usages.length) {
45+
let specifier = root.find(j.ImportSpecifier, {
5746
local: {
5847
name
5948
}
6049
})
61-
.filter(filterAndRemoveImports)
50+
if (!specifier.length) {
51+
specifier = root.find(j.ImportDefaultSpecifier, {
52+
local: {
53+
name
54+
}
55+
})
56+
}
57+
58+
if (!specifier.length) {
59+
return
60+
}
61+
62+
const decl = specifier.closest(j.ImportDeclaration)
63+
const declNode = decl.get(0).node
64+
const peerSpecifiers = declNode.specifiers
65+
const source = declNode.source.value
66+
67+
// these modules are known to have no side effects
68+
const safelyRemovableModules = ['vue', 'vue-router', 'vuex']
69+
if (
70+
peerSpecifiers.length === 1 &&
71+
safelyRemovableModules.includes(source)
72+
) {
73+
decl.remove()
74+
} else {
75+
// otherwise, only remove the specifier
76+
specifier.remove()
77+
}
78+
}
6279
}

0 commit comments

Comments
 (0)