anchengjian/vue-nw-seed

额外使用node-printer和serialport模块提示的部分错误

kaensoft opened this issue · 6 comments

使用vue-nw-seed已经可以把项目跑起来了,赞seed一个!!

现在需要额外使用2个node模块,分别报了些错误,不知道是还有哪里的配置问题?
还是这2个额外的模块自身的语法问题?

  1. node-printer 和 serialport 都已经用nw-gyp重新编译过了

  2. 然后再webpack的配置里也添加了node-loader,可以正常加载*.node的文件
    {
    test: /.node$/,
    loader: 'node-loader'
    }

  3. vue里就只写的简单的require代码,


var printer = require('printer')
console.log('.........printer', printer)


var serialport = require('serialport')
console.log('.........serialport', serialport)

其中2个模块报的分别错误如下:

  1. node-printer连接打印机打印 (https://github.com/tojocky/node-printer)
    printer.js?91b6:12
    Uncaught Error: Cannot find module "."
    webpackMissingModule @ printer.js?91b6:12
    (anonymous function) @ printer.js?91b6:12
    (anonymous function) @ VM499:326
    (anonymous function) @ app.js:1314
    webpack_require @ app.js:660
    fn @ app.js:86
    getPrinter @ App.vue?32b4:31

  2. node-serialport读写串口设备的数据 (https://github.com/EmergingTechnologyAdvisors/node-serialport)
    ncaught TypeError: Path must be a string. Received undefined
    assertPath @ path.js:7dirname @ path.js:697

NW.js 里有点扯淡的就是必须用 nw-gyp 打包,不要用 node-gyp 打包,你再试试。

不对啊,我看你是重新编译过的,等下,我再想想

确定 nw-gyp 编译时的版本和运行的 node-webkit 版本一致,还有就是区分了 64 位和 32 位的,32位的用 --arch=ia32
再试试呢

恩,对的,用nw-gyp编译过的,target也指定到了特定的nwjs版本,位数对应好的,x64的

最新的进展,用相对路径的形式,把node-printer的找不到模块的问题解决了

原来的代码:

var printer_helper = {},
    fs = require("fs"),
    child_process = require("child_process"),
    os = require("os"),
    path = require("path"),
    native_lib_path = path.join(__dirname, '../build/Release/node_printer.node'),
    printer_helper;

if(fs.existsSync(native_lib_path)) {
    printer_helper = require(native_lib_path);
} else {
    printer_helper = require('./node_printer_'+process.platform+'_'+process.arch+'.node');
}

上面这串代码里fs.existsSync的判断,找不到这个路径
估计还是vue+nw+webpack的环境里,文件的路径不对了

直接修改代码,跳过这个ifelse的判断,用相对路径引入node-printer.node,成功加载printer这个模块了

var printer_helper = {},
    fs = require("fs"),
    child_process = require("child_process"),
    os = require("os"),
    path = require("path"),
    native_lib_path = path.join(__dirname, '../build/Release/node_printer.node'),
    printer_helper;

// if(fs.existsSync(native_lib_path)) {
//     printer_helper = require(native_lib_path);
// } else {
//     printer_helper = require('./node_printer_'+process.platform+'_'+process.arch+'.node');
// }

printer_helper = require('../build/Release/node_printer.node');

serialport那个模块的问题,还在进一步找

fs.existsSync 这儿的逻辑感觉有问题,这个方法判断的是文件是否存在于硬盘中,然而 native_lib_path 这个你期望拼接出来的是相对于项目的一个绝对路径,但实际上在开发的过程中,这段代码运行在 /node_modules/nw/nwjs/nw.exe 下,这个时候的 __dirname 不是项目的根路径哦。

所以,直接拼接出来再用 fs.existsSync 判断肯定要出问题。

直接 require 不出问题,是因为 webpack 帮你处理了这种路径转换。

建议不要这么判断依赖是否存在,直接 tryRquire 一下就好了

// tryRquire.js
var cwd = process.cwd()
var resolve = require('resolve')

// attempts to first require a dep using projects cwd (when vue-loader is linked)
// then try a normal require.
module.exports = function tryRequire (dep) {
  var fromCwd
  try {
    fromCwd = resolve.sync(dep, { basedir: cwd })
  } catch (e) {}
  if (fromCwd) {
    return require(fromCwd)
  } else {
    try {
      return require(dep)
    } catch (e) {}
  }
}

恩,serialport这个模块的错误,最终发现也是路径require造成的问题
serialport模块下lib\bindings\win32.js 文件里的第二行,把引用路径改成相对路径,也最终成功引入了serialport这个模块

原来的代码
const binding = require('bindings')('serialport.node');

直接修改为相对路径,
const binding = require('../../build/Release/serialport.node');

暂时能让整个项目工程和模块按需要跑起来了,恩,先用着
webpack不熟,只能是直接先改这2个模块的源码了
: )