UNPKG

npminstall

Version:

Make npm install fast and handy.

69 lines (64 loc) 2.49 kB
const debug = require('node:util').debuglog('npminstall:download:local'); const { randomUUID } = require('node:crypto'); const fs = require('node:fs/promises'); const { createReadStream } = require('node:fs'); const path = require('node:path'); const chalk = require('chalk'); const utils = require('../utils'); module.exports = async (pkg, options) => { const { fetchSpec, displayName, } = pkg; options.localPackages++; let filepath = fetchSpec; try { filepath = await fs.realpath(filepath); const stat = await fs.stat(filepath); return stat.isDirectory() ? await localFolder(filepath, pkg, options) : await localTarball(filepath, pkg, options); } catch (err) { throw new Error(`[${displayName}] resolved target ${filepath} error: ${err.message}`); } }; async function localFolder(filepath, pkg, options) { debug(`install ${pkg.name}@${pkg.rawSpec} from local folder ${filepath}`); try { // everytime copy to a different directory to avoid parallel install const tmpDir = path.join(options.storeDir, '.tmp', randomUUID()); await utils.mkdirp(tmpDir); // use npm pack to ensure npmignore/gitignore/package.files work fine const res = await utils.exec(`npm pack --pack-destination ${tmpDir}`, { cwd: filepath }); if (res && res.stdout) { const tarball = path.join(tmpDir, res.stdout.trim()); try { return await localTarball(tarball, pkg, options); } finally { await utils.rimraf(tarball); } } } catch (err) { // fallback to copy options.console.warn(`[npminstall:download:local] install ${pkg.displayName} from local folder ${filepath} with npm pack failed(${err.message}), use copy`); return await utils.copyInstall(filepath, options); } } async function localTarball(filepath, pkg, options) { debug(`install ${pkg.name}@${pkg.rawSpec} from local tarball ${filepath}`); const readstream = createReadStream(filepath); // everytime unpack to a different directory const ungzipDir = path.join(options.storeDir, '.tmp', randomUUID()); await utils.mkdirp(ungzipDir); try { await utils.unpack(readstream, ungzipDir, pkg); return await utils.copyInstall(ungzipDir, options); } finally { // clean up try { await utils.rimraf(ungzipDir); } catch (err) { options.console.warn(chalk.yellow(`[npminstall:download:local] ${pkg.displayName} rmdir local ungzip dir: ${ungzipDir} error: ${err}, ignore it`)); } } }