This repository has been archived by the owner on May 22, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 35
/
plugin_native_modules.ts
80 lines (61 loc) · 2.58 KB
/
plugin_native_modules.ts
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
import path from 'path'
import type { Plugin } from '@netlify/esbuild'
import readPackageJson from 'read-package-json-fast'
import { isNativeModule } from '../../utils/detect_native_module.js'
import { PackageJson } from '../../utils/package_json.js'
import type { NativeNodeModules } from '../index.js'
type NativeModuleCacheEntry = [boolean | undefined, PackageJson]
type NativeModuleCache = Record<string, Promise<NativeModuleCacheEntry>>
// Filters out relative or absolute file paths.
const packageFilter = /^([^./]*)$/
// Filters valid package names and extracts the base directory.
const packageName = /^([^@][^/]*|@[^/]*\/[^/]+)(?:\/|$)/
const findNativeModule = (packageJsonPath: string, cache: NativeModuleCache) => {
if (cache[packageJsonPath] === undefined) {
// eslint-disable-next-line no-param-reassign, promise/prefer-await-to-then
cache[packageJsonPath] = readPackageJson(packageJsonPath).then(
(data) => [Boolean(isNativeModule(data)), data],
() => [undefined, {}],
)
}
return cache[packageJsonPath]
}
export const getNativeModulesPlugin = (externalizedModules: NativeNodeModules): Plugin => ({
name: 'external-native-modules',
setup(build) {
const cache: NativeModuleCache = {}
// eslint-disable-next-line complexity, max-statements
build.onResolve({ filter: packageFilter }, async (args) => {
const pkg = packageName.exec(args.path)
if (!pkg) return
let directory = args.resolveDir
while (true) {
if (path.basename(directory) !== 'node_modules') {
const modulePath = path.join(directory, 'node_modules', pkg[1])
const packageJsonPath = path.join(modulePath, 'package.json')
const [isNative, packageJsonData] = await findNativeModule(packageJsonPath, cache)
// eslint-disable-next-line max-depth
if (isNative === true) {
// eslint-disable-next-line max-depth
if (externalizedModules[args.path] === undefined) {
// eslint-disable-next-line no-param-reassign
externalizedModules[args.path] = {}
}
// eslint-disable-next-line no-param-reassign
externalizedModules[args.path][modulePath] = packageJsonData.version
return { path: args.path, external: true }
}
// eslint-disable-next-line max-depth
if (isNative === false) {
return
}
}
const parentDirectory = path.dirname(directory)
if (parentDirectory === directory) {
break
}
directory = parentDirectory
}
})
},
})