MCPcopy
hub / github.com/evanw/esbuild / installUsingNPM

Function installUsingNPM

lib/npm/node-install.ts:105–149  ·  view source on GitHub ↗
(pkg: string, subpath: string, binPath: string)

Source from the content-addressed store, hash-verified

103}
104
105function installUsingNPM(pkg: string, subpath: string, binPath: string): void {
106 // Erase "npm_config_global" so that "npm install --global esbuild" works.
107 // Otherwise this nested "npm install" will also be global, and the install
108 // will deadlock waiting for the global installation lock.
109 const env = { ...process.env, npm_config_global: undefined }
110
111 // Create a temporary directory inside the "esbuild" package with an empty
112 // "package.json" file. We'll use this to run "npm install" in.
113 const esbuildLibDir = path.dirname(require.resolve('esbuild'))
114 const installDir = path.join(esbuildLibDir, 'npm-install')
115 fs.mkdirSync(installDir)
116 try {
117 fs.writeFileSync(path.join(installDir, 'package.json'), '{}')
118
119 // Run "npm install" in the temporary directory which should download the
120 // desired package. Try to avoid unnecessary log output. This uses the "npm"
121 // command instead of a HTTP request so that it hopefully works in situations
122 // where HTTP requests are blocked but the "npm" command still works due to,
123 // for example, a custom configured npm registry and special firewall rules.
124 child_process.execSync(`npm install --loglevel=error --prefer-offline --no-audit --progress=false ${pkg}@${packageJSON.version}`,
125 { cwd: installDir, stdio: 'pipe', env })
126
127 // Move the downloaded binary executable into place. The destination path
128 // is the same one that the JavaScript API code uses so it will be able to
129 // find the binary executable here later.
130 const installedBinPath = path.join(installDir, 'node_modules', pkg, subpath)
131 binaryIntegrityCheck(pkg, subpath, fs.readFileSync(installedBinPath))
132 fs.renameSync(installedBinPath, binPath)
133 } finally {
134 // Try to clean up afterward so we don't unnecessarily waste file system
135 // space. Leaving nested "node_modules" directories can also be problematic
136 // for certain tools that scan over the file tree and expect it to have a
137 // certain structure.
138 try {
139 removeRecursive(installDir)
140 } catch {
141 // Removing a file or directory can randomly break on Windows, returning
142 // EBUSY for an arbitrary length of time. I think this happens when some
143 // other program has that file or directory open (e.g. an anti-virus
144 // program). This is fine on Unix because the OS just unlinks the entry
145 // but keeps the reference around until it's unused. There's nothing we
146 // can do in this case so we just leave the directory there.
147 }
148 }
149}
150
151function removeRecursive(dir: string): void {
152 for (const entry of fs.readdirSync(dir)) {

Callers 1

checkAndPreparePackageFunction · 0.85

Calls 4

removeRecursiveFunction · 0.85
resolveMethod · 0.80
joinMethod · 0.80
binaryIntegrityCheckFunction · 0.70

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…