最近用到node模块knex(需要用它来操作mysql),npm install安装时遇到错误:
简单分析错误提示及处理逻辑,发现是knex包用到sqlite3这个包,而用于node的sqlite3是需要随不同系统而进行本地编译生成的。提示未定义的module_name变量就出现在编译配置文件building.gyp中,另外还有module_path等。再进一步分析相关命令模块node-gyp及node-pre-gyp(它们是借助python2来编译c语言的文件的,详细可以查资料进一步了解)知道这些变量是node-pre-gyp用到的,它会自动获取在sqlite3的package.json中定义的这些变量,但直接运行node-gyp rebuild时却无法获取package.json中的定义(虽然node-pre-gyp的readme.md中说可以传递变量值)。命令是自动顺序执行的,出错后一切回滚,之前过程创建的node_modules文件夹会被删除,因此无法手动干预修改。所以从项目的package.json中移除knex依赖项,先npm install 完成其他项目,再npm install knex单独安装knex,结果还是不行,出错仍然回滚,只是这次是删除node_modules中的knex及sqlite3等刚安装的内容。看来也行不通。
然后就开始了一天的搜索,相关内容不算多,但也不少,sqlite3的github主页就许多issues,但都没有这种情况的解决方案,而且绝大多数都没有分析明白,有的是降sqlite3版本,有的是单独用到sqlite3这一个包自然可以手动运行命令通过--module_name=xxxx的方式来传递变量值(其中有一位提到了用node-pre-gyp rebuild的方式来运行)。
最后实在没办法,突然想换用 cnpm 试下:
居然不出错,不回滚了!knex没有自动安装sqlite3等包。然后再手动安装:
这样就安装上了,检查一下sqlite3包中已有编译好的文件:node_modules\sqlite3\lib\binding\napi-v3-win32-x64\node_sqlite3.node,应该是因为国内的大师们考虑到或者遇到这个情况,替我们做了准备工作了。因为程序检测到已经有编译结果时就不会再自动编译,所以能正常安装了。
如果想尝试编译,稍微体验一下也是可以的:进入node_modules\sqlite3,输入命令node-pre-gyp rebuild(不能使用node-gyp,否则还是会出现变量未定义错误)
要注意的是,系统中事先安装了vs2017与python2.7,这都是编译时用到的,python3不可以,其中有的python代码是2.x版本的,或许不久之后相关包的作者会修改下。