Skip to content

Commit 7c60957

Browse files
committed
feat: add options.ignore
1 parent 72f2555 commit 7c60957

2 files changed

Lines changed: 56 additions & 55 deletions

File tree

src/index.ts

Lines changed: 43 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import type { NodeLoaderOptions, WebpackAssetRelocatorLoader } from './types'
1111
import { COLOURS } from 'vite-plugin-utils/function'
1212
import {
1313
type NativeRecord,
14-
type NativeRecordType,
1514
createCjs,
1615
ensureDir,
1716
getInteropSnippet,
@@ -22,8 +21,13 @@ import {
2221
export interface NativeOptions {
2322
/** @default 'node_natives' */
2423
assetsDir?: string
25-
/** By default native modules are automatically detected if this option is not explicitly configure by the user. */
24+
/**
25+
* By default native modules are automatically detected if this option is not explicitly configure by the user.
26+
* @deprecated use `ignore` option instead
27+
*/
2628
natives?: string[] | ((natives: string[]) => string[])
29+
/** Ignore the specified native module. */
30+
ignore?: (name: string) => boolean | undefined
2731
/** Enable and configure webpack. */
2832
webpack?: {
2933
config?: (config: Configuration) => Configuration | undefined | Promise<Configuration | undefined>
@@ -44,8 +48,7 @@ const nativesMap = new Map<string, {
4448
status: 'built' | 'resolved'
4549
nativeFilename: string
4650
interopFilename: string
47-
type: NativeRecordType
48-
nodeFiles: string[]
51+
native: NativeRecord
4952
}>
5053

5154
export default function native(options: NativeOptions): Plugin {
@@ -61,21 +64,16 @@ export default function native(options: NativeOptions): Plugin {
6164
const outDir = config.build?.outDir ?? 'dist'
6265
output = normalizePath(path.join(resolvedRoot, outDir, assetsDir))
6366

64-
const depsNativeRecord = await getDependenciesNatives(resolvedRoot)
65-
const depsNatives = [...depsNativeRecord.keys()]
67+
let nativeRecord = await getDependenciesNatives(resolvedRoot)
6668

6769
if (options.natives) {
6870
const natives = Array.isArray(options.natives)
6971
? options.natives
70-
: options.natives(depsNatives)
72+
: options.natives([...nativeRecord.keys()])
7173
// TODO: bundle modules based on `natives`.
7274
}
7375

7476
const withDistAssetBase = (p: string) => (assetsDir && p) ? `${assetsDir}/${p}` : p
75-
76-
let detectedNativeRecord: NativeRecord = new Map
77-
let detectedNatives: string[] = []
78-
7977
const alias: Alias = {
8078
find: /(.*)/,
8179
// Keep `customResolver` receive original source.
@@ -85,54 +83,51 @@ export default function native(options: NativeOptions): Plugin {
8583
if (!importer) return
8684
if (!bareImportRE.test(source)) return
8785

88-
if (!depsNativeRecord.has(source)) {
89-
// Auto detection.
86+
if (!nativeRecord.has(source)) {
87+
// Dynamic deep detection.
9088
// e.g. serialport -> @serialport/bindings-cpp
91-
const nativeRecord = await resolveNativeRecord(source, importer)
92-
if (nativeRecord) {
93-
detectedNativeRecord = new Map([...detectedNativeRecord, ...nativeRecord])
94-
detectedNatives = [...depsNativeRecord.keys()]
95-
}
89+
nativeRecord = new Map([...nativeRecord, ...(await resolveNativeRecord(source, importer) ?? [])])
9690
}
9791

98-
if ([...depsNatives, ...detectedNatives].includes(source)) {
99-
const nativeFilename = path.join(output, source + NativeExt)
100-
const interopFilename = path.join(output, source + InteropExt)
92+
const nativeItem = nativeRecord.get(source)
93+
if (!nativeItem) return
10194

102-
if (!nativesMap.get(source)) {
103-
ensureDir(output)
95+
if (options.ignore?.(source) === false) {
96+
nativeItem.ignore = true
97+
return
98+
}
10499

105-
// Generate Vite and Webpack interop file.
106-
fs.writeFileSync(
107-
interopFilename,
108-
getInteropSnippet(source, `./${withDistAssetBase(source + NativeExt)}`),
109-
)
100+
const nativeFilename = path.join(output, source + NativeExt)
101+
const interopFilename = path.join(output, source + InteropExt)
110102

111-
// We did not immediately call the `webpackBundle()` build here
112-
// because `build.emptyOutDir = true` will cause the built file to be removed.
103+
if (!nativesMap.get(source)) {
104+
ensureDir(output)
113105

114-
const isDetected = detectedNativeRecord.has(source)
106+
// Generate Vite and Webpack interop file.
107+
fs.writeFileSync(
108+
interopFilename,
109+
getInteropSnippet(source, `./${withDistAssetBase(source + NativeExt)}`),
110+
)
115111

116-
// Collect modules that are explicitly used.
117-
nativesMap.set(source, {
118-
status: 'resolved',
119-
nativeFilename,
120-
interopFilename,
121-
type: isDetected ? 'detected' : 'dependencies',
122-
nodeFiles: isDetected
123-
? detectedNativeRecord.get(source)?.nativeFiles!
124-
: depsNativeRecord.get(source)?.nativeFiles!,
125-
})
126-
}
112+
// We did not immediately call the `webpackBundle()` build here
113+
// because `build.emptyOutDir = true` will cause the built file to be removed.
127114

128-
return { id: interopFilename }
115+
// Collect modules that are explicitly used.
116+
nativesMap.set(source, {
117+
status: 'resolved',
118+
nativeFilename,
119+
interopFilename,
120+
native: nativeItem,
121+
})
129122
}
123+
124+
return { id: interopFilename }
130125
},
131126
}
132127

133128
modifyAlias(config, [alias])
134129
// Run build are not necessary.
135-
modifyOptimizeDeps(config, [...depsNatives, ...detectedNatives])
130+
modifyOptimizeDeps(config, [...nativeRecord.keys()])
136131
},
137132
async buildEnd(error) {
138133
if (error) return
@@ -258,3 +253,7 @@ async function webpackBundle(
258253
})
259254
})
260255
}
256+
257+
async function ensureNodeFiles() {
258+
259+
}

src/utils.ts

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,12 @@ import glob from 'fast-glob'
66
import _libEsm from 'lib-esm'
77
import { node_modules as findNodeModules } from 'vite-plugin-utils/function'
88

9-
export type NativeRecordType = 'dependencies' | 'detected'
10-
export type NativeRecord = Map<string, {
11-
type: NativeRecordType
9+
export interface NativeRecord {
10+
type: 'dependencies' | 'detected'
1211
path: string
1312
nativeFiles: string[]
14-
}>
13+
ignore?: true
14+
}
1515

1616
// @ts-ignore
1717
const libEsm: typeof import('lib-esm').default = _libEsm.default || _libEsm
@@ -39,10 +39,10 @@ export async function globNativeFiles(cwd: string) {
3939
return nativeFiles
4040
}
4141

42-
export async function getDependenciesNatives(root = process.cwd()): Promise<NativeRecord> {
42+
export async function getDependenciesNatives(root = process.cwd()): Promise<Map<string, NativeRecord>> {
4343
const node_modules_paths = findNodeModules(root)
4444
// Native modules of package.json
45-
const natives: NativeRecord = new Map
45+
const natives = new Map<string, NativeRecord>
4646

4747
for (const node_modules_path of node_modules_paths) {
4848
const pkgId = path.join(node_modules_path, '../package.json')
@@ -52,6 +52,8 @@ export async function getDependenciesNatives(root = process.cwd()): Promise<Nati
5252
const deps = Object.keys(pkg.dependencies || {}).concat(Object.keys(pkg.devDependencies || {}))
5353

5454
for (const dep of deps) {
55+
if (natives.has(dep)) continue
56+
5557
const depPath = path.join(node_modules_path, dep)
5658
const nativeFiles = await globNativeFiles(depPath)
5759

@@ -90,7 +92,7 @@ export function ensureDir(dir: string) {
9092
return dir
9193
}
9294

93-
export async function resolveNativeRecord(source: string, importer: string): Promise<NativeRecord | undefined> {
95+
export async function resolveNativeRecord(source: string, importer: string): Promise<Map<string, NativeRecord> | undefined> {
9496
let modulePath: string | undefined
9597
try {
9698
const modulePackageJson = cjs.require.resolve(`${source}/package.json`, {
@@ -100,11 +102,11 @@ export async function resolveNativeRecord(source: string, importer: string): Pro
100102
} catch { }
101103

102104
if (modulePath) {
103-
const nodeFiles = await globNativeFiles(modulePath)
104-
return new Map().set(source, {
105-
type: 'deep-dependencies',
105+
const nativeFiles = await globNativeFiles(modulePath)
106+
return new Map<string, NativeRecord>().set(source, {
107+
type: 'detected',
106108
path: modulePath,
107-
nodeFiles,
109+
nativeFiles,
108110
})
109111
}
110112
}

0 commit comments

Comments
 (0)