sharp.js 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. // Copyright 2013 Lovell Fuller and others.
  2. // SPDX-License-Identifier: Apache-2.0
  3. 'use strict';
  4. // Inspects the runtime environment and exports the relevant sharp.node binary
  5. const { familySync, versionSync } = require('detect-libc');
  6. const { runtimePlatformArch, isUnsupportedNodeRuntime, prebuiltPlatforms, minimumLibvipsVersion } = require('./libvips');
  7. const runtimePlatform = runtimePlatformArch();
  8. const paths = [
  9. `../src/build/Release/sharp-${runtimePlatform}.node`,
  10. '../src/build/Release/sharp-wasm32.node',
  11. `@img/sharp-${runtimePlatform}/sharp.node`,
  12. '@img/sharp-wasm32/sharp.node'
  13. ];
  14. let sharp;
  15. const errors = [];
  16. for (const path of paths) {
  17. try {
  18. sharp = require(path);
  19. break;
  20. } catch (err) {
  21. /* istanbul ignore next */
  22. errors.push(err);
  23. }
  24. }
  25. /* istanbul ignore next */
  26. if (sharp) {
  27. module.exports = sharp;
  28. } else {
  29. const [isLinux, isMacOs, isWindows] = ['linux', 'darwin', 'win32'].map(os => runtimePlatform.startsWith(os));
  30. const help = [`Could not load the "sharp" module using the ${runtimePlatform} runtime`];
  31. errors.forEach(err => {
  32. if (err.code !== 'MODULE_NOT_FOUND') {
  33. help.push(`${err.code}: ${err.message}`);
  34. }
  35. });
  36. const messages = errors.map(err => err.message).join(' ');
  37. help.push('Possible solutions:');
  38. // Common error messages
  39. if (isUnsupportedNodeRuntime()) {
  40. const { found, expected } = isUnsupportedNodeRuntime();
  41. help.push(
  42. '- Please upgrade Node.js:',
  43. ` Found ${found}`,
  44. ` Requires ${expected}`
  45. );
  46. } else if (prebuiltPlatforms.includes(runtimePlatform)) {
  47. const [os, cpu] = runtimePlatform.split('-');
  48. const libc = os.endsWith('musl') ? ' --libc=musl' : '';
  49. help.push(
  50. '- Ensure optional dependencies can be installed:',
  51. ' npm install --include=optional sharp',
  52. '- Ensure your package manager supports multi-platform installation:',
  53. ' See https://sharp.pixelplumbing.com/install#cross-platform',
  54. '- Add platform-specific dependencies:',
  55. ` npm install --os=${os.replace('musl', '')}${libc} --cpu=${cpu} sharp`
  56. );
  57. } else {
  58. help.push(
  59. `- Manually install libvips >= ${minimumLibvipsVersion}`,
  60. '- Add experimental WebAssembly-based dependencies:',
  61. ' npm install --cpu=wasm32 sharp',
  62. ' npm install @img/sharp-wasm32'
  63. );
  64. }
  65. if (isLinux && /(symbol not found|CXXABI_)/i.test(messages)) {
  66. try {
  67. const { config } = require(`@img/sharp-libvips-${runtimePlatform}/package`);
  68. const libcFound = `${familySync()} ${versionSync()}`;
  69. const libcRequires = `${config.musl ? 'musl' : 'glibc'} ${config.musl || config.glibc}`;
  70. help.push(
  71. '- Update your OS:',
  72. ` Found ${libcFound}`,
  73. ` Requires ${libcRequires}`
  74. );
  75. } catch (errEngines) {}
  76. }
  77. if (isLinux && /\/snap\/core[0-9]{2}/.test(messages)) {
  78. help.push(
  79. '- Remove the Node.js Snap, which does not support native modules',
  80. ' snap remove node'
  81. );
  82. }
  83. if (isMacOs && /Incompatible library version/.test(messages)) {
  84. help.push(
  85. '- Update Homebrew:',
  86. ' brew update && brew upgrade vips'
  87. );
  88. }
  89. if (errors.some(err => err.code === 'ERR_DLOPEN_DISABLED')) {
  90. help.push('- Run Node.js without using the --no-addons flag');
  91. }
  92. // Link to installation docs
  93. if (isWindows && /The specified procedure could not be found/.test(messages)) {
  94. help.push(
  95. '- Using the canvas package on Windows?',
  96. ' See https://sharp.pixelplumbing.com/install#canvas-and-windows',
  97. '- Check for outdated versions of sharp in the dependency tree:',
  98. ' npm ls sharp'
  99. );
  100. }
  101. help.push(
  102. '- Consult the installation documentation:',
  103. ' See https://sharp.pixelplumbing.com/install'
  104. );
  105. throw new Error(help.join('\n'));
  106. }