This repository has been archived by the owner on Jan 3, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
138 lines (120 loc) · 4.04 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
var fs = require('fs')
var path = require('path')
// opts passed through .babelrc as second argument
// {
// "plugins": [["tipsi-flavors", { "env": "APP_NAME", "flavors": ["custom", "tipsi"]}]]
// }
function resolveFlavors(opts) {
var string = process.env[opts.env || 'FLAVORS']
if (string) {
return string.split(',')
} else if (opts.flavors) {
return opts.flavors
}
return []
}
function resolveImport(source, file, flavors) {
var dirpath = path.dirname(file)
if (!flavors.length) {
return undefined
}
var parsedSourceName = path.parse(source)
// If there is "dir" property as an empty string
// Looks like it's a module
// Don't do anything with it
if (!parsedSourceName.dir) {
return undefined
}
var parsedExtension = parsedSourceName.ext
var isFlavorExtension = flavors.indexOf(parsedExtension.replace('.', '')) !== -1
var isJSExtension = parsedExtension === '.js'
var isEmptyExtension = !parsedExtension
var isAnotherFileTypeExtension = !(isFlavorExtension || isJSExtension || isEmptyExtension)
var correctExtension = isAnotherFileTypeExtension ? parsedExtension : '.js'
var expectedPath
if (parsedExtension !== '.') {
for (var i = 0; i < flavors.concat('').length; i += 1) {
var suffix = flavors[i]
var correctSuffix = suffix ? '.' + suffix : ''
var pathname = path.resolve(
dirpath,
parsedSourceName.dir,
parsedSourceName.name + correctSuffix + correctExtension
)
var isExist = fs.existsSync(pathname)
if (isExist) {
expectedPath = [path.dirname(source), path.basename(pathname)].join('/')
// We care about file extensions
// If source code doesn't contain '.js' extension,
// we will not pass it through transpiled code
if (!isAnotherFileTypeExtension && !source.endsWith('.js')) {
expectedPath = expectedPath.slice(0, expectedPath.length - 3)
}
break
}
}
}
// If we will not return undefined while expectedPath === source
// babel will infinitely visit updated paths
// and transform them again and again
return expectedPath !== source ? expectedPath : undefined
}
module.exports = function(babel) {
var t = babel.types
function checkRequire(path) {
var callee = path.node.callee
var isId = t.isIdentifier
var isMember = t.isMemberExpression
var obj = { name: 'require' }
return !isId(callee, obj) && !(isMember(callee) && isId(callee.object, obj))
}
function transform(path, state, isRequireCall, needSpecifiers = true) {
if (isRequireCall && checkRequire(path)) {
return
}
var expression = path.node.type // CallExpression, ImportDeclaration, ExportAllDeclaration and etc
var source = isRequireCall ? path.node.arguments[0] : path.node.source
if (source && source.type === 'StringLiteral') {
var flavors = resolveFlavors(state.opts)
var modulePath = resolveImport(source.value, state.file.opts.filename, flavors)
if (modulePath) {
var specifiersValue = isRequireCall ? path.node.callee : path.node.specifiers
var pathValue = t.stringLiteral(modulePath)
if (needSpecifiers) {
var replacement = t[expression](
specifiersValue,
isRequireCall ? [pathValue] : pathValue
)
} else {
/* Will be something like:
{ type: 'ExportAllDeclaration',
source:
{ type: 'StringLiteral',
value: './exportFilesTest/moduleExport.tipsi' } }
*/
var replacement = t[expression](pathValue)
}
path.replaceWith(replacement)
}
}
}
return {
visitor: {
CallExpression: {
exit: function(path, state) {
return transform(path, state, true)
},
},
ImportDeclaration: {
exit: function(path, state) {
return transform(path, state)
},
},
ExportAllDeclaration: {
exit: function(path, state) {
return transform(path, state, false, false)
},
},
},
}
}