-
Notifications
You must be signed in to change notification settings - Fork 2
/
index.js
98 lines (75 loc) · 2.01 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
import path from 'node:path'
import glob from 'fast-glob'
const filter = /\*/
const namespace = 'plugin-glob-imports'
export default function (opts) {
opts ??= {}
opts.camelCase ??= true
opts.entryPoint ??= 'index.js'
opts.entryPointMatch ??= arr => arr[arr.length - 1] === opts.entryPoint
return {
name: namespace,
setup (build) {
build.onResolve({ filter }, resolve)
build.onLoad({ filter, namespace }, args => load(args, opts))
}
}
}
function camelCase (filename) {
return filename
.replace(/\.[^.]+$/, '') // removes extension
.replace(/[-_](\w)/g, (match, letter) => letter.toUpperCase())
}
function resolve (args) {
const resolvePaths = []
const loadpath = path.join(args.resolveDir, args.path)
let files = glob.sync(loadpath)
files = files.length === 0 ? [loadpath] : files
for (let i = 0; i < files.length; i++) {
resolvePaths.push(path.relative(args.resolveDir, files[i]))
}
return {
namespace,
path: args.path,
pluginData: {
resolveDir: args.resolveDir,
resolvePaths
}
}
}
function load (args, opts) {
const pluginData = args.pluginData
const paths = pluginData.resolvePaths
const data = []
const obj = {}
for (let i = 0; i < paths.length; i++) {
const filepath = paths[i]
const arr = filepath.split('/')
const name = '_module' + i
arr.shift()
if (opts.entryPointMatch?.(arr)) {
arr.pop()
}
let prev = obj
for (let i = 0; i < arr.length; i++) {
let key = arr[i]
if (typeof prev === 'string') {
continue
}
if (opts.camelCase) {
key = camelCase(key)
}
if (i === arr.length - 1) {
data.push(`import ${prev[key] = name} from './${filepath}'`)
continue
}
prev = prev[key] ??= {}
}
}
let output = JSON.stringify(obj)
output = output.replace(/"_module\d+"/g, match => match.slice(1, -1))
return {
resolveDir: pluginData.resolveDir,
contents: data.join('\n') + '\nexport default ' + output
}
}