折腾:
【未解决】给gitbook install的npm添加代理无效
期间,去研究
1 | git install |
输出的log
1 2 3 4 5 | xxx@xxx ~ /dev/crifan/gitbook/gitbook_template/books/gitbook_demo master ● gitbook install info: installing 18 plugins using npm@3.9.2 info: info: installing plugin "google-adsense" info: install plugin "google-adsense" (*) from NPM with version 0.1.0 |

另外,从报错中:
1 2 3 4 5 6 7 8 9 10 | at ReadStream.Readable.on (_stream_readable.js:849:29) at untarStream ( /Users/xxx/ .gitbook /versions/3 .2.3 /node_modules/npm/lib/fetch-package-metadata .js:304:8) at addShrinkwrap ( /Users/xxx/ .gitbook /versions/3 .2.3 /node_modules/npm/lib/fetch-package-metadata .js:200:3) at /Users/xxx/ .gitbook /versions/3 .2.3 /node_modules/npm/lib/fetch-package-metadata .js:185:14 at /Users/xxx/ .gitbook /versions/3 .2.3 /node_modules/npm/node_modules/iferr/index .js:13:50 at RES ( /Users/xxx/ .gitbook /versions/3 .2.3 /node_modules/npm/node_modules/inflight/inflight .js:23:14) at f ( /Users/xxx/ .gitbook /versions/3 .2.3 /node_modules/npm/node_modules/once/once .js:17:25) at /Users/xxx/ .gitbook /versions/3 .2.3 /node_modules/npm/lib/cache .js:362:16 at /Users/xxx/ .gitbook /versions/3 .2.3 /node_modules/npm/node_modules/write-file-atomic/index .js:29:9 at LOOP ( /Users/xxx/ .gitbook /versions/3 .2.3 /node_modules/npm/node_modules/slide/lib/chain .js:7:26) |
可以看出:
内部调用到了:
1 | /Users/xxx/ .gitbook /versions/3 .2.3 |
下面的npm
1 | node_modules /npm |
想要搞清楚内部npm内部如何用上代理。
/Users/xxx/.gitbook/versions/3.2.3/package.json
1 2 3 4 5 | { "name" : "gitbook" , "version" : "3.2.3" , "description" : "Library and cmd utility to generate GitBooks" , |
其中的:
3.2.3是gitbook的版本
搜:
install
找到了:
/Users/xxx/.gitbook/versions/3.2.3/lib/cli/index.js
1 2 3 4 5 6 7 8 9 10 11 12 13 | var buildEbook = require( './buildEbook' ); module.exports = [ require( './build' ), require( './serve' ), require( './install' ), require( './parse' ), require( './init' ), buildEbook( 'pdf' ), buildEbook( 'epub' ), buildEbook( 'mobi' ) ]; |
除了install
还要很多,比如pdf/epub/mobi等格式,和之前的build/serve/init等命令
引用的是
/Users/xxx/.gitbook/versions/3.2.3/lib/cli/install.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | var options = require( './options' ); var getBook = require( './getBook' ); var Parse = require( '../parse' ); var Plugins = require( '../plugins' ); module.exports = { name: 'install [book]' , description: 'install all plugins dependencies' , options: [ options.log ], exec : function(args, kwargs) { var book = getBook(args, kwargs); return Parse.parseConfig(book) .then(function(resultBook) { return Plugins.installPlugins(resultBook); }); } }; |
此处引用的是:
Plugins.installPlugins
通过加了:
1 | console.info( "book=%o" , book) |
调试打印出:
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 | gitbook install book = Record { "logger" : [ object Object ], "fs" : Record { "root" : "/Users/xxx/dev/crifan/gitbook/gitbook_template/books/gitbook_demo" , "fsExists" : function fileExists(filename) { var d = Promise.defer(); fs.exists(filename, function(exists) { d.resolve(exists); }); return d.promise; }, "fsReadFile" : function () { var nodeArgs = baseArgs.concat(array_slice(arguments)); var deferred = defer(); nodeArgs.push(deferred.makeNodeResolver()); Q(callback).fapply(nodeArgs).fail(deferred.reject); return deferred.promise; }, "fsStatFile" : function () { var nodeArgs = baseArgs.concat(array_slice(arguments)); var deferred = defer(); nodeArgs.push(deferred.makeNodeResolver()); Q(callback).fapply(nodeArgs).fail(deferred.reject); return deferred.promise; }, "fsReadDir" : function fsReadDir(folder) { return fs.readdir(folder) .then(function(files) { files = Immutable. List (files); return files . map (function( file ) { if ( file = = '.' || file = = '..' ) return ; var stat = fs.statSync(path.join(folder, file )); if (stat.isDirectory()) file = file + path.sep; return file ; }) . filter (function( file ) { return Boolean( file ); }); }); }, "fsLoadObject" : function fsLoadObject(filename) { return fresh(filename, require); }, "fsReadAsStream" : function createReadStream (path, options) { return new ReadStream(path, options) } }, "ignore" : Ignore { "ignore" : [ object Object ] }, "config" : Config { "file" : Record { "path" : " ", " mtime ": " Wed Jan 20 2021 21 : 04 : 04 GMT + 0800 (中国标准时间) " }, " values ": Map { " gitbook ": " * ", " theme ": " default ", " variables ": Map {}, " plugins ": List [], " pluginsConfig ": Map {}, " structure ": Map { " langs ": " LANGS.md ", " readme ": " README.md ", " glossary ": " GLOSSARY.md ", " summary ": " SUMMARY.md " }, " pdf ": Map { " pageNumbers ": true, " fontSize ": 12, " fontFamily ": " Arial ", " paperSize ": " a4 ", " chapterMark ": " pagebreak ", " pageBreaksBefore ": " / ", " margin ": Map { " right ": 62, " left ": 62, " top ": 56, " bottom ": 56 } } } }, " readme ": Record { " file ": Record { " path ": " ", " mtime ": " Wed Jan 20 2021 21 : 04 : 04 GMT + 0800 (中国标准时间) " }, " title ": " ", " description ": " " }, " summary ": Summary { " file ": Record { " path ": " ", " mtime ": " Wed Jan 20 2021 21 : 04 : 04 GMT + 0800 (中国标准时间) " }, " parts ": List [] }, " glossary ": Record { " file ": Record { " path ": " ", " mtime ": " Wed Jan 20 2021 21 : 04 : 04 GMT + 0800 (中国标准时间) " }, " entries ": OrderedMap {} }, " languages ": Record { " file ": Record { " path ": " ", " mtime ": " Wed Jan 20 2021 21 : 04 : 04 GMT + 0800 (中国标准时间) " }, " list ": OrderedMap {} }, " language ": " ", " books": OrderedMap {} } (node: 1340 ) [DEP0079] DeprecationWarning: Custom inspection function on Objects via .inspect() is deprecated 。。。 |
另外:
1 | console.info( "resultBook=%o" , resultBook) |
输出类似。
/Users/xxx/.gitbook/versions/3.2.3/lib/plugins/installPlugins.js
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 | var npmi = require( 'npmi' ); var DEFAULT_PLUGINS = require( '../constants/defaultPlugins' ); var Promise = require( '../utils/promise' ); var installPlugin = require( './installPlugin' ); / * * Install plugin requirements for a book @param {Book} @ return {Promise<Number>} * / function installPlugins(book) { var logger = book.getLogger(); var config = book.getConfig(); var plugins = config.getPluginDependencies(); / / Remove default plugins / / (only if version is same as installed) plugins = plugins.filterNot(function(plugin) { var dependency = DEFAULT_PLUGINS.find(function(dep) { return dep.getName() = = = plugin.getName(); }); return ( / / Disabled plugin !plugin.isEnabled() || / / Or default one installed in GitBook itself (dependency && plugin.getVersion() = = = dependency.getVersion()) ); }); if (plugins.size = = 0 ) { logger.info.ln( 'nothing to install!' ); return Promise(); } logger.info.ln( 'installing' , plugins.size, 'plugins using npm@' + npmi.NPM_VERSION); return Promise.forEach(plugins, function(plugin) { return installPlugin(book, plugin); }) .thenResolve(plugins.size); } module.exports = installPlugins; |
去打印:
1 | console.info( "config=%o" , config) |
出:
1 | config = Config { "file" : Record { "path" : "book.json" , "mtime" : Wed Jan 20 2021 16 : 47 : 19 GMT + 0800 (中国标准时间) }, "values" : Map { "plugins" : List [ "google-adsense" , "theme-comscore" , "anchors" , "-lunr" , "-search" , "search-plus" , "disqus" , "-highlight" , "prism" , "prism-themes" , "github-buttons" , "splitter" , "-sharing" , "sharing-plus" , "tbfed-pagefooter" , "expandable-chapters-small" , "ga" , "donate" , "sitemap-general" , "copy-code-button" , "callouts" , "toolbar-button" ], "root" : "./src" , "pluginsConfig" : Map { "tbfed-pagefooter" : Map { "copyright" : "crifan.com,使用<a href='https://creativecommons.org/licenses/by/4.0/deed.zh'>署名4.0国际(CC BY 4.0)协议</a>发布" , "modify_label" : "最后更新:" , "modify_format" : "YYYY-MM-DD HH:mm:ss" }, "prism" : Map { "css" : List [ "prism-themes/themes/prism-atom-dark.css" ] }, "disqus" : Map { "shortName" : "crifan" }, "callouts" : Map { "showTypeInHeader" : false }, "toolbar-button" : Map { "url" : "http://book.crifan.com/books/gitbook_demo/pdf/gitbook_demo.pdf" , "icon" : "fa-file-pdf-o" , "label" : "下载PDF" }, "autocover" : Map { "title" : "Gitbook演示" , "author" : "Crifan Li <xxx>" , "font" : Map { "size" : null, "family" : "Impact" , "color" : "#FFF" }, "size" : Map { "w" : 1800 , "h" : 2360 }, "background" : Map { "color" : "#09F" } }, "donate" : Map { "wechat" : "https://www.crifan.com/files/res/crifan_com/crifan_wechat_pay.jpg" , "alipay" : "https://www.crifan.com/files/res/crifan_com/crifan_alipay_pay.jpg" , "title" : " ", " button ": " 打赏 ", " alipayText ": " 支付宝打赏给Crifan ", " wechatText ": " 微信打赏给Crifan " }, " sitemap - general ": Map { " prefix ": " https: / / book.crifan.com / gitbook / gitbook_demo / website / " }, " google - adsense ": Map { " ads ": List [ Map { " client ": " ca - pub - 6626240105039250 " } ] }, " github - buttons ": Map { " buttons ": List [ Map { " repo ": " gitbook_demo ", " user ": " crifan ", " type ": " star ", " count ": true, " size ": " small " }, Map { " user ": " crifan ", " type ": " follow ", " width ": " 120 ", " count ": false, " size ": " small " } ] }, " ga ": Map { " token ": " UA - 28297199 - 1 " }, " sharing ": Map { " qq ": true, " all ": List [ " douban ", " facebook ", " google ", " instapaper ", " line ", " linkedin ", " messenger ", " pocket ", " qq ", " qzone ", " stumbleupon ", " twitter ", " viber ", " vk ", " weibo ", " whatsapp " ], " douban ": false, " facebook ": true, " weibo ": true, " instapaper ": false, " whatsapp ": false, " hatenaBookmark ": false, " twitter ": true, " messenger ": false, " line ": false, " vk ": false, " pocket ": false, " google ": false, " viber ": false, " stumbleupon ": false, " qzone ": false, " linkedin ": false }, " theme - default ": Map { " showLevel ": true } }, " theme ": " default ", " author ": " Crifan Li <xxx> ", " pdf ": Map { " pageNumbers ": true, " fontSize ": 12, " fontFamily ": " Arial ", " paperSize ": " a4 ", " chapterMark ": " pagebreak ", " pageBreaksBefore ": " / ", " margin ": Map { " right ": 62, " left ": 62, " top ": 56, " bottom ": 56 } }, " structure ": Map { " langs ": " LANGS.md ", " readme ": " README.md ", " glossary ": " GLOSSARY.md ", " summary ": " SUMMARY.md " }, " variables ": Map {}, " title ": " Gitbook演示 ", " language ": " zh - hans ", " links ": Map { " sidebar ": Map { " 主页 ": " https: / / www.crifan.com " } }, " gitbook ": " 3.2 . 3 ", " description ": " crifan的Gitbook模版,用于演示如何用Gitbook创建一个自己的book电子书" } } |
就是我们的gitbook_demo的配置
1 | console.info( "plugins=%o" , plugins) |
输出:
1 | plugins = List [ PluginDependency { "name" : "google-adsense" , "version" : "*" , "enabled" : true }, PluginDependency { "name" : "theme-comscore" , "version" : "*" , "enabled" : true }, PluginDependency { "name" : "anchors" , "version" : "*" , "enabled" : true }, PluginDependency { "name" : "search-plus" , "version" : "*" , "enabled" : true }, PluginDependency { "name" : "disqus" , "version" : "*" , "enabled" : true }, PluginDependency { "name" : "prism" , "version" : "*" , "enabled" : true }, PluginDependency { "name" : "prism-themes" , "version" : "*" , "enabled" : true }, PluginDependency { "name" : "github-buttons" , "version" : "*" , "enabled" : true }, PluginDependency { "name" : "splitter" , "version" : "*" , "enabled" : true }, PluginDependency { "name" : "sharing-plus" , "version" : "*" , "enabled" : true }, PluginDependency { "name" : "tbfed-pagefooter" , "version" : "*" , "enabled" : true }, PluginDependency { "name" : "expandable-chapters-small" , "version" : "*" , "enabled" : true }, PluginDependency { "name" : "ga" , "version" : "*" , "enabled" : true }, PluginDependency { "name" : "donate" , "version" : "*" , "enabled" : true }, PluginDependency { "name" : "sitemap-general" , "version" : "*" , "enabled" : true }, PluginDependency { "name" : "copy-code-button" , "version" : "*" , "enabled" : true }, PluginDependency { "name" : "callouts" , "version" : "*" , "enabled" : true }, PluginDependency { "name" : "toolbar-button" , "version" : "*" , "enabled" : true } ] |
是此处的插件列表
继续:
/Users/xxx/.gitbook/versions/3.2.3/lib/plugins/installPlugin.js
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 | var npmi = require( 'npmi' ); var Promise = require( '../utils/promise' ); var resolveVersion = require( './resolveVersion' ); / * * Install a plugin for a book @param {Book} @param {PluginDependency} @ return {Promise} * / function installPlugin(book, plugin) { var logger = book.getLogger(); var installFolder = book.getRoot(); var name = plugin.getName(); var requirement = plugin.getVersion(); logger.info.ln(''); logger.info.ln( 'installing plugin "' + name + '"'); // Find a version to install return resolveVersion(plugin) .then(function(version) { if (!version) { throw new Error('Found no satisfactory version for plugin "' + name + '" with requirement "' + requirement + '"' ); } logger.info.ln( 'install plugin "' + name + '" (' + requirement + ') from NPM with version' , version); return Promise.nfcall(npmi, { 'name' : plugin.getNpmID(), 'version' : version, 'path' : installFolder, 'npmLoad' : { 'loglevel' : 'silent' , 'loaded' : true, 'prefix' : installFolder } }); }) .then(function() { logger.info.ok( 'plugin "' + name + '" installed with success' ); }); } module.exports = installPlugin; |
貌似核心的是:
1 | return Promise.nfcall(npmi, { |
看到函数原型是:
/Users/xxx/Library/Caches/typescript/4.1/node_modules/@types/q/index.d.ts
1 2 3 4 5 6 7 8 9 10 11 12 13 | /** * Calls a Node.js-style function with the given variadic arguments, returning a promise that is fulfilled if the * Node.js function calls back with a result, or rejected if it calls back with an error * (or throws one synchronously). An example: * * @example * Q.nfcall(FS.readFile, "foo.txt", "utf-8").done(function (text) { * }); * * The same warning about functions vs. methods applies for nfcall as it does for nfapply. In this case, the better * strategy would be to use Q.ninvoke. */ export function nfcall<T>(nodeFunction: (...args: any[]) => any, ...args: any[]): Promise<T>; |
此处:
- nodeFunction=npmi
- args = 此处json=dict
1 2 3 4 5 6 7 8 9 | { 'name' : plugin.getNpmID(), 'version' : version, 'path' : installFolder, 'npmLoad' : { 'loglevel' : 'silent' , 'loaded' : true , 'prefix' : installFolder } |
/Users/xxx/.gitbook/versions/3.2.3/node_modules/npmi/npmi.js
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 | var npm = require( 'npm' ); var fs = require( 'fs' ); var path = require( 'path' ); var semver = require( 'semver' ); var LOAD_ERR = 'NPM_LOAD_ERR' , INSTALL_ERR = 'NPM_INSTALL_ERR' , VIEW_ERR = 'NPM_VIEW_ERR' ; / * * * Created with IntelliJ IDEA. * User: leiko * Date: 30 / 01 / 14 * Time: 10 : 28 * / var npmi = function (options, callback) { callback = callback || function () {}; var name = options.name, pkgName = options.pkgName || name, version = options.version || 'latest' , installPath = options.path || '.' , forceInstall = options.forceInstall || false, localInstall = options.localInstall || false, npmLoad = options.npmLoad || {loglevel: 'silent' }, savedPrefix = null; function viewCallback(installedVersion) { 。。。 function checkInstalled(isTarball) { 。。。 function installCallback(err, result) { / / reset npm.prefix to saved value npm.prefix = savedPrefix; if (err) { err.code = INSTALL_ERR; } callback(err, result); } 。。。 function loadCallback(err) { 。。。 npmi.LOAD_ERR = LOAD_ERR; npmi.INSTALL_ERR = INSTALL_ERR; npmi.VIEW_ERR = VIEW_ERR; npmi.NPM_VERSION = npm.version; module.exports = npmi; |
感觉是:
此处报错就是调用了installCallback,发生了error
试试:
1 2 3 | // callback(err, result); console.info( "err=%o" , err) console.info( "result=%o" , result) |
输出:
好像没有多余输出。
另外去看:
loadCallback
1 | console.info( "loadCallback:err=%o" , err) |
没有
1 | console.info( "checkInstalled: isTarball=%o" , isTarball) |
结果:
没有
1 2 | function viewCallback(installedVersion) { console.info( "viewCallback: installedVersion=%o" , installedVersion) |
也没有。
1 2 | var npmi = function (options, callback) { console.info( "npmi: options=%o" , options) |
结果:也没有。
看来不是这个文件。
1 | console.info( "in npmi" ) |
有输出,确定是加载了:
/Users/xxx/.gitbook/versions/3.2.3/node_modules/npmi/npmi.js
搜npmi
找到
/Users/xxx/.gitbook/versions/3.2.3/package.json
1 2 | "npm" : "3.9.2" , "npmi" : "2.0.1" , |
1 2 3 | console.info( "npmLoad=%o" , npmLoad) console.info( "loadCallback=%o" , loadCallback) npm.load(npmLoad, loadCallback); |
结果:没有
/Users/xxx/.gitbook/versions/3.2.3/node_modules/npm/package.json
1 2 3 | "bin" : { "npm" : "./bin/npm-cli.js" }, |
去看看
/Users/xxx/.gitbook/versions/3.2.3/node_modules/npm/bin/npm-cli.js
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 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 | #!/usr/bin/env node ;(function () { / / wrapper in case we're in module_context mode / / windows: running "npm blah" in this folder will invoke WSH, not node. / * global WScript * / if (typeof WScript ! = = 'undefined' ) { WScript.echo( 'npm does not work when run\n' + 'with the Windows Scripting Host\n\n' + "'cd' to a different directory,\n" + "or type 'npm.cmd <args>',\n" + "or type 'node npm <args>'." ) WScript.quit( 1 ) return } process.title = 'npm' var log = require( 'npmlog' ) log.pause() / / will be unpaused when config is loaded. log.info( 'it worked if it ends with' , 'ok' ) var path = require( 'path' ) var npm = require( '../lib/npm.js' ) var npmconf = require( '../lib/config/core.js' ) var errorHandler = require( '../lib/utils/error-handler.js' ) var configDefs = npmconf.defs var shorthands = configDefs.shorthands var types = configDefs.types var nopt = require( 'nopt' ) / / if npm is called as "npmg" or "npm_g" , then / / run in global mode. if (path.basename(process.argv[ 1 ]). slice ( - 1 ) = = = 'g' ) { process.argv.splice( 1 , 1 , 'npm' , '-g' ) } log.verbose( 'cli' , process.argv) var conf = nopt(types, shorthands) npm.argv = conf.argv.remain if (npm.deref(npm.argv[ 0 ])) npm.command = npm.argv.shift() else conf.usage = true if (conf.version) { console.log(npm.version) return } if (conf.versions) { npm.command = 'version' conf.usage = false npm.argv = [] } log.info( 'using' , 'npm@%s' , npm.version) log.info( 'using' , 'node@%s' , process.version) process.on( 'uncaughtException' , errorHandler) if (conf.usage && npm.command ! = = 'help' ) { npm.argv.unshift(npm.command) npm.command = 'help' } / / now actually fire up npm and run the command. / / this is how to use npm programmatically: conf._exit = true npm.load(conf, function (er) { if (er) return errorHandler(er) npm.commands[npm.command](npm.argv, errorHandler) }) })() #!/usr/bin/env node ;(function () { / / wrapper in case we're in module_context mode / / windows: running "npm blah" in this folder will invoke WSH, not node. / * global WScript * / if (typeof WScript ! = = 'undefined' ) { WScript.echo( 'npm does not work when run\n' + 'with the Windows Scripting Host\n\n' + "'cd' to a different directory,\n" + "or type 'npm.cmd <args>',\n" + "or type 'node npm <args>'." ) WScript.quit( 1 ) return } process.title = 'npm' var log = require( 'npmlog' ) log.pause() / / will be unpaused when config is loaded. log.info( 'it worked if it ends with' , 'ok' ) var path = require( 'path' ) var npm = require( '../lib/npm.js' ) var npmconf = require( '../lib/config/core.js' ) var errorHandler = require( '../lib/utils/error-handler.js' ) var configDefs = npmconf.defs var shorthands = configDefs.shorthands var types = configDefs.types var nopt = require( 'nopt' ) / / if npm is called as "npmg" or "npm_g" , then / / run in global mode. if (path.basename(process.argv[ 1 ]). slice ( - 1 ) = = = 'g' ) { process.argv.splice( 1 , 1 , 'npm' , '-g' ) } log.verbose( 'cli' , process.argv) var conf = nopt(types, shorthands) npm.argv = conf.argv.remain if (npm.deref(npm.argv[ 0 ])) npm.command = npm.argv.shift() else conf.usage = true if (conf.version) { console.log(npm.version) return } if (conf.versions) { npm.command = 'version' conf.usage = false npm.argv = [] } log.info( 'using' , 'npm@%s' , npm.version) log.info( 'using' , 'node@%s' , process.version) process.on( 'uncaughtException' , errorHandler) if (conf.usage && npm.command ! = = 'help' ) { npm.argv.unshift(npm.command) npm.command = 'help' } / / now actually fire up npm and run the command. / / this is how to use npm programmatically: conf._exit = true npm.load(conf, function (er) { if (er) return errorHandler(er) npm.commands[npm.command](npm.argv, errorHandler) }) })() |
另外还有
/Users/xxx/.gitbook/versions/3.2.3/node_modules/npm/bin/npm.cmd
/Users/xxx/.gitbook/versions/3.2.3/node_modules/npm/bin/npm
1 | console.info( "in versions/3.2.3/node_modules/npm/bin/npm-cli.js" ) |
结果:没输出。
回去注意到
/Users/xxx/.gitbook/versions/3.2.3/lib/plugins/installPlugin.js
1 2 3 | // Find a version to install return resolveVersion(plugin) . then ( function (version) { |
去看看
/Users/xxx/.gitbook/versions/3.2.3/lib/plugins/resolveVersion.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | / * * Resolve a plugin dependency to a version @param {PluginDependency} plugin @ return {Promise<String>} * / function resolveVersion(plugin) { var npmId = Plugin.nameToNpmID(plugin.getName()); var requiredVersion = plugin.getVersion(); if (plugin.isGitDependency()) { return Promise.resolve(requiredVersion); } ... |
用:
1 2 | function resolveVersion(plugin) { console.info( "plugin=%o" , plugin) |
输出:
1 | plugin=PluginDependency { "name" : "google-adsense" , "version" : "*" , "enabled" : true } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | function resolveVersion(plugin) { console.info( "plugin=%o" , plugin) var npmId = Plugin.nameToNpmID(plugin.getName()); console.info( "npmId=%o" , npmId) var requiredVersion = plugin.getVersion(); console.info( "requiredVersion=%o" , requiredVersion) if (plugin.isGitDependency()) { console.info( "plugin.isGitDependency is True" ) return Promise.resolve(requiredVersion); } return initNPM() .then(function() { console.info( "complete initNPM" ) console.info( "npm.commands=%o" , npm.commands) console.info( "npm.commands.view=%o" , npm.commands.view) return Promise.nfcall(npm.commands.view, [npmId + '@' + requiredVersion, 'engines' ], true); }) |
输出:
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 | plugin=PluginDependency { "name" : "google-adsense" , "version" : "*" , "enabled" : true } npmId= 'gitbook-plugin-google-adsense' requiredVersion= '*' (node:2659) [DEP0079] DeprecationWarning: Custom inspection function on Objects via .inspect() is deprecated complete initNPM npm.commands={ [ac]: [Getter], [acc]: [Getter], [acce]: [Getter], [acces]: [Getter], access: [Getter], [add-]: [Getter], [add-u]: [Getter], 。。。 [whoam]: [Getter], whoami: [Getter], [build]: [Getter], [unbuild]: [Getter], [xmas]: [Getter], [substack]: [Getter], [visnup]: [Getter] } npm.commands.view={ [Function] [length]: 0, [name]: '' , [arguments]: null , [caller]: null , [prototype]: { [constructor]: [Circular] }, usage: 'npm view [<@scope>/]<pkg>[@<version>] [<field>[.subfield]...]\n\naliases: v, info, show' , completion: { [Function] [length]: 2, [name]: '' , [arguments]: null , [caller]: null , [prototype]: { [constructor]: [Circular] } } } |
看到是:
1 | npm view [<@scope>/]<pkg>[@<version>] [<field>[.subfield]...]\n\naliases: v, info, show |
想到去:
1 2 3 | xxx@xxx ~/.gitbook /versions/3 .2.3 /node_modules/npm bin /npm-cli .js --version in versions /3 .2.3 /node_modules/npm/bin/npm-cli .js 3.9.2 |
-》实现了我们希望的,至少找到了:npm对应的二进制是哪个