UNPKG

@speedy-js/depcost

Version:

[![npm version](https://badgen.net/npm/v/@speedy-js/depcost)](https://npm.im/@speedy-js/depcost)

198 lines (169 loc) 5.36 kB
const fs = require('fs-extra') const path = require('path') const log = require('npmlog') const execa = require('execa') const requireFromString = require('require-from-string') const { DepCost, DepCostEvents } = require('./dep-cost') const requirePkg = require('./require-pkg') const loadConfig = require('./load-config') function getPkgByDependencies(dependencies) { return Object.keys(dependencies).map(name => { const range = dependencies[name] let version if (range === '*') { version = '' } else { version = range.replace(/^(~|\^)/, '') } return version ? `${name}@${version}` : name }) } module.exports = async opts => { opts.cwd = opts.cwd || process.cwd() let masterPkgName = '' let pkgs = opts.pkgs || [] if (opts.debug) { opts.logLevel = 'debug' } const localConfig = await loadConfig() opts = { npmClient: 'npm', ...localConfig, ...opts, } let dependencies = {} let devDependencies = {} if (opts.dependencies || opts.devDependencies) { if (opts.pkgs.length > 1) { throw new Error(`length of pkgs under 'dependencies' or 'devDependencies' mode should be 1 or 1, but got ${pkgs}`) } const currentPkg = pkgs[0] if (currentPkg) { masterPkgName = currentPkg // TODO Error handling if (opts.allDependencies || opts.dependencies) { const { stdout } = await execa(opts.npmClient, ['view', currentPkg, 'dependencies']) dependencies = requireFromString(`module.exports = ${stdout}`) } if (opts.allDependencies || opts.devDependencies) { const { stdout } = await execa(opts.npmClient, ['view', currentPkg, 'devDependencies']) devDependencies = requireFromString(`module.exports = ${stdout}`) } } else { const packageJson = requirePkg(opts.cwd) masterPkgName = packageJson.name if (opts.allDependencies || opts.dependencies) { dependencies = packageJson.dependencies } if (opts.allDependencies || opts.devDependencies) { devDependencies = packageJson.devDependencies } } const dependenciesPkgs = getPkgByDependencies(dependencies) const devDependenciesPkgs = getPkgByDependencies(devDependencies) if (opts.allDependencies) { pkgs = [...dependenciesPkgs, ...devDependenciesPkgs] } else if (opts.dependencies) { pkgs = dependenciesPkgs } else if (opts.devDependencies) { pkgs = dependenciesPkgs } } else if (opts.monorepo) { const loadMonorepoPackages = require('./load-monorepo-packages') const monorepoPaackages = loadMonorepoPackages(opts.cwd) .filter(pkg => !!(pkg.name && pkg.version && !pkg.private)) .map(pkg => `${pkg.name}@${pkg.version}`) pkgs = [ ...pkgs, ...monorepoPaackages, ] } log.level = opts.logLevel || 'warn' log.info('pkgs', pkgs) log.info('opts', opts) const program = new DepCost({ ...opts, pkgs, }) let isFirst = false const results = [] program.on(DepCostEvents.message, result => { results.push(result) if (opts.table) { if (!isFirst) { isFirst = true console.log(`| name | install size | reuqire time | | --- | --- | --- |`) } console.log( `| ${result.pkg} | ${result.size} | ${result.requireTime} |`, ) } else { if (!isFirst) { isFirst = true console.log('name\t\t\tinstall size\t\treuqire time') } console.log(`${result.pkg}\t\t\t${result.size}\t\t${result.requireTime}`) } }) program.runAndEmit().then(() => { log.info('results', results) let content = '' if (opts.record) { if (pkgs.length === 0) { const packageJson = requirePkg(opts.cwd) content += `## ${packageJson.version}\n` } if (opts.monorepo) { const { loadMonorepoConfig } = require('./load-monorepo-packages') const config = loadMonorepoConfig(opts.cwd) content += `## ${config.version}\n` } content += ` | name | install size | reuqire time | | --- | --- | --- | ${results.map(result => `| ${result.pkg} | ${result.size} | ${result.requireTime} |`).join('\n')} ` const RECORD_FILE = 'DEPCOST.md' const recordFile = path.join(opts.cwd, RECORD_FILE) if (fs.existsSync(recordFile)) { const existedContent = fs.readFileSync(recordFile, 'utf-8') content = `${content.trim()}\n\n\n${existedContent}` } fs.writeFileSync(recordFile, content) return content } if (opts.visualization) { const VisualizationServer = require('./visualization/server') const server = new VisualizationServer({ masterPkgName, pkgs, content, dependencies, devDependencies, results, }) server.bootstrap() server.listen(null, null, async url => { const open = require('open') await open(url) }) } if (opts.html) { const generateReportHTML = require('./visualization/html') generateReportHTML(results, { cwd: opts.cwd, writeFile: true, }) } return { content, results, dependencies, devDependencies, } }).catch(error => { process.exitCode = 1 console.log(require('chalk').red(error.stack)) }) }