Skip to content

Commit

Permalink
Simplify logic to determine installation help
Browse files Browse the repository at this point in the history
  • Loading branch information
lovell committed Nov 6, 2023
1 parent 8c5a493 commit 0740043
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 57 deletions.
4 changes: 2 additions & 2 deletions docs/install.md
Original file line number Diff line number Diff line change
Expand Up @@ -118,11 +118,11 @@ When building your deployment package on a machine that differs from the target
you will need to install either `@img/sharp-linux-x64` or `@img/sharp-linux-arm64` package.

```sh
npm install --os=linux --cpu=x64
npm install --os=linux --cpu=x64 sharp
```

```sh
npm install --os=linux --cpu=arm64
npm install --os=linux --cpu=arm64 sharp
```

When using npm 9 or earlier, this can be achieved using the following:
Expand Down
117 changes: 63 additions & 54 deletions lib/sharp.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,62 +9,71 @@ const { familySync, versionSync } = require('detect-libc');

const { runtimePlatformArch, prebuiltPlatforms, minimumLibvipsVersion } = require('./libvips');
const runtimePlatform = runtimePlatformArch();
const [isLinux, isMacOs, isWindows] = ['linux', 'darwin', 'win32'].map(os => runtimePlatform.startsWith(os));

/* istanbul ignore next */
try {
// Check for local build
module.exports = require(`../src/build/Release/sharp-${runtimePlatform}.node`);
} catch (errLocal) {
const paths = [
`../src/build/Release/sharp-${runtimePlatform}.node`,
`@img/sharp-${runtimePlatform}/sharp.node`
];

const errors = [];
for (const path of paths) {
try {
// Check for runtime package
module.exports = require(`@img/sharp-${runtimePlatform}/sharp.node`);
} catch (errPackage) {
const help = ['Could not load the "sharp" module at runtime'];
if (errLocal.code !== 'MODULE_NOT_FOUND') {
help.push(`${errLocal.code}: ${errLocal.message}`);
}
if (errPackage.code !== 'MODULE_NOT_FOUND') {
help.push(`${errPackage.code}: ${errPackage.message}`);
}
help.push('Possible solutions:');
// Common error messages
if (prebuiltPlatforms.includes(runtimePlatform)) {
const [os, cpu] = runtimePlatform.split('-');
help.push('- Add an explicit dependency for the runtime platform:');
help.push(` npm install --os=${os} --cpu=${cpu} sharp`);
help.push(' or');
help.push(` npm install --force @img/sharp-${runtimePlatform}`);
} else {
help.push(`- The ${runtimePlatform} platform requires manual installation of libvips >= ${minimumLibvipsVersion}`);
}
if (isLinux && /symbol not found/i.test(errPackage)) {
try {
const { engines } = require(`@img/sharp-libvips-${runtimePlatform}/package`);
const libcFound = `${familySync()} ${versionSync()}`;
const libcRequires = `${engines.musl ? 'musl' : 'glibc'} ${engines.musl || engines.glibc}`;
help.push('- Update your OS:');
help.push(` Found ${libcFound}`);
help.push(` Requires ${libcRequires}`);
} catch (errEngines) {}
}
if (isMacOs && /Incompatible library version/.test(errLocal.message)) {
help.push('- Update Homebrew:');
help.push(' brew update && brew upgrade vips');
}
if (errPackage.code === 'ERR_DLOPEN_DISABLED') {
help.push('- Run Node.js without using the --no-addons flag');
}
if (process.versions.pnp) {
help.push('- Use a supported yarn linker, either pnpm or node-modules:');
help.push(' yarn config set nodeLinker node-modules');
}
// Link to installation docs
if (isWindows && /The specified procedure could not be found/.test(errPackage.message)) {
help.push('- Using the canvas package on Windows? See https://sharp.pixelplumbing.com/install#canvas-and-windows');
} else {
help.push('- Consult the installation documentation: https://sharp.pixelplumbing.com/install');
module.exports = require(path);
break;
} catch (err) {
/* istanbul ignore next */
errors.push(err);
}
}

/* istanbul ignore next */
if (!module.exports) {
const [isLinux, isMacOs, isWindows] = ['linux', 'darwin', 'win32'].map(os => runtimePlatform.startsWith(os));

const help = [`Could not load the "sharp" module using the ${runtimePlatform} runtime`];
errors.forEach(err => {
if (err.code !== 'MODULE_NOT_FOUND') {
help.push(`${err.code}: ${err.message}`);
}
throw new Error(help.join('\n'));
});
const messages = errors.map(err => err.message).join(' ');
help.push('Possible solutions:');
// Common error messages
if (prebuiltPlatforms.includes(runtimePlatform)) {
const [os, cpu] = runtimePlatform.split('-');
help.push('- Add platform-specific dependencies:');
help.push(` npm install --os=${os} --cpu=${cpu} sharp`);
help.push(' or');
help.push(` npm install --force @img/sharp-${runtimePlatform}`);
} else {
help.push(`- Manually install libvips >= ${minimumLibvipsVersion}`);
}
if (isLinux && /symbol not found/i.test(messages)) {
try {
const { engines } = require(`@img/sharp-libvips-${runtimePlatform}/package`);
const libcFound = `${familySync()} ${versionSync()}`;
const libcRequires = `${engines.musl ? 'musl' : 'glibc'} ${engines.musl || engines.glibc}`;
help.push('- Update your OS:');
help.push(` Found ${libcFound}`);
help.push(` Requires ${libcRequires}`);
} catch (errEngines) {}
}
if (isMacOs && /Incompatible library version/.test(messages)) {
help.push('- Update Homebrew:');
help.push(' brew update && brew upgrade vips');
}
if (errors.some(err => err.code === 'ERR_DLOPEN_DISABLED')) {
help.push('- Run Node.js without using the --no-addons flag');
}
if (process.versions.pnp) {
help.push('- Use a supported yarn linker, either pnpm or node-modules:');
help.push(' yarn config set nodeLinker node-modules');
}
// Link to installation docs
if (isWindows && /The specified procedure could not be found/.test(messages)) {
help.push('- Using the canvas package on Windows? See https://sharp.pixelplumbing.com/install#canvas-and-windows');
} else {
help.push('- Consult the installation documentation: https://sharp.pixelplumbing.com/install');
}
throw new Error(help.join('\n'));
}
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@
"@img/sharp-libvips-win32-ia32": "0.0.3",
"@img/sharp-libvips-win32-x64": "0.0.3",
"@types/node": "*",
"async": "^3.2.4",
"async": "^3.2.5",
"cc": "^3.0.1",
"exif-reader": "^2.0.0",
"extract-zip": "^2.0.1",
Expand Down

0 comments on commit 0740043

Please sign in to comment.