# 安装步骤:

前提:Node.js 安装 Canvas 之前,需要首先安装 node-gyp。 而想要安装 node-gyp,需要首先安装 windows-build-tools。 执行命令:

npm install --global --production windows-build-tools

执行命令后,会自动安装 Visual C++ Build Environment 和 Python2.7。

然后就可以安装 node-gyp 了

npm install -g node-gyp

安装后,下载 GTK 2 以及 libjpeg-turbo SDK for Visual C++,请根据系统选择 32 位或者 64 位下载。

GTK2:32 位 gtk±bundle_2.24.10-20120208_win32.zip (opens new window) GTK2:64 位 gtk±bundle_2.22.1-20101229_win64.zip (opens new window)

libjpeg-turbo:32 位 libjpeg-turbo-1.5.2-vc.exe (opens new window) libjpeg-turbo:64 位 libjpeg-turbo-1.5.2-vc64.exe (opens new window)

GTK2 默认安装 C:\GTK,如安装其它目录,需要执行命令

node-gyp rebuild --GTK_Root=C:\somewhere\GTK

libjpeg-turbo 默认安装 32 位 C:\libjpeg-turbo 或 64 位 C:\libjpeg-turbo64,如安装其它目录,需要执行命令

node-gyp rebuild --jpeg_root=C:\somewhere\libjpeg-turbo

完成后,执行安装 Canvas 命令即可安装。

npm install canvas

# 后记

最后一步安装 Canvas 时,有一个隐藏的坑。如果 Windows 登录用户名存在中文的话,部分目录会含有中文。导致安装出现错误。

c:\users\中文用户名\appdata\roaming\npm\node_modules\canvas\src\backend\ImageBackend.h(4): fatal error C1083: 无法打开包括文件: “v8.h”: No such file or directory (编译源文件 ..
\src\backend\ImageBackend.cc) [C:\Users\中文用户名\AppData\Roaming\npm\node_modules\canvas\build\canvas.vcxproj]
c:\users\中文用户名\appdata\roaming\npm\node_modules\canvas\src\backend\PdfBackend.h(4): fatal error C1083: 无法打开包括文件: “v8.h”: No such file or directory (编译源文件 ..\s
rc\backend\PdfBackend.cc) [C:\Users\中文用户名\AppData\Roaming\npm\node_modules\canvas\build\canvas.vcxproj]
  Backends.cc
c:\users\中文用户名\appdata\roaming\npm\node_modules\canvas\src\backend\SvgBackend.h(4): fatal error C1083: 无法打开包括文件: “v8.h”: No such file or directory (编译源文件 ..\s
rc\backend\SvgBackend.cc) [C:\Users\中文用户名\AppData\Roaming\npm\node_modules\canvas\build\canvas.vcxproj]

经过调试,此坑是由于 node-gyp 在生成编译文件时,XML 格式的配置文件会有转码问题,不包含中文的话,转码正常。包含中文后,由于 Windows 系统是使用 GBK,而 Python 使用 UTF-8 导致错误。

具体问题出现在 easy_xml.py 文件内。打开 easy_xml.py 文件,找到 119 行左右,如下代码:

try:
  xml_string = xml_string.encode(encoding)
except Exception:
  xml_string = unicode(xml_string, 'latin-1').encode(encoding)
# Get the old content
try:
  f = open(path, 'r')
  existing = f.read()
  f.close()
except:
  existing = None
if existing != xml_string:
  f = open(path, 'w')
  f.write(xml_string)
  f.close()

将代码替换为:

try:
  if path.endswith('vcxproj'):
    xml_string = xml_string
  else:
    xml_string = xml_string.encode(encoding)
except Exception:
  xml_string = unicode(xml_string, 'latin-1').encode(encoding)
# Get the old content
try:
  f = open(path, 'r')
  existing = f.read()
  f.close()
  existing = None
# It has changed, write it
if existing != xml_string:
  if path.endswith('vcxproj'):
    #use utf_8 encoding to generate vcxproj file
    f = codecs.open(path, 'w', 'utf_8_sig')
    #f = open(path, 'w')
    #convert GBK string to Unicode string to ensure the later utf_8 encoding
    f.write(xml_string.decode('gbk'))
  else:
    f = open(path, 'w')
    f.write(xml_string)
  f.close()

主要需要判断生成的.vcxproj 项目配置文件时,避免 xml_string 被初始化编码。并在写文件时,将 xml_string 从 GBK 解码,并且打开的文件也设置成 utf_8_sig 编码类型即可。

关于 easy_xml.py 可能会存在两个位置,一个是 Windows 程序数据目录,一个是 Node.js 的安装目录。

C:\Users\王锐\AppData\Roaming\npm\node_modules\node-gyp\gyp\pylib\gyp\easy_xml.py
C:\Program Files\nodejs\node_modules\npm\node_modules\node-gyp\gyp\pylib\gyp\easy_xml.py

如果执行 node-gyp 的命令,会调用第一个路径下的文件,执行 npm 命令,会调用第二个路径下的文件。

# 参考内容

  1. node-canvas: Installation Windows (opens new window)
  2. nodejs 安装模块出现 MSB4025 错误 (opens new window)

Windows 中安装 Canvas 插件 (opens new window)