diff --git a/.gitignore b/.gitignore index 3a85452d..780e5c46 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ -build +src/build +src/node_modules node_modules /coverage npm/*/* diff --git a/docs/changelog.md b/docs/changelog.md index 6bbd42c5..6d92ffa2 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -8,6 +8,10 @@ Requires libvips v8.14.5 * Drop support for Node.js 14 and 16, now requires Node.js >= 18.17.0 +* Prebuilt binaries distributed via npm registry and installed via package manager. + +* Building from source requires dependency on `node-addon-api`. + * Remove `sharp.vendor`. * Make `compression` option of `heif` mandatory to help reduce HEIF vs HEIC confusion. diff --git a/docs/install.md b/docs/install.md index 20ae28d3..68200997 100644 --- a/docs/install.md +++ b/docs/install.md @@ -53,9 +53,15 @@ This module will be compiled from source at `npm install` time when: Building from source requires: * C++11 compiler +* [node-addon-api](https://www.npmjs.com/package/node-addon-api) * [node-gyp](https://github.com/nodejs/node-gyp#installation) and its dependencies -If `node-gyp` cannot be found, try adding it to `devDependencies`. +There is an install-time check for these dependencies. +If `node-addon-api` or `node-gyp` cannot be found, try adding them via: + +```sh +npm install --save node-addon-api node-gyp +``` For cross-compiling, the `--platform`, `--arch` and `--libc` npm flags (or the `npm_config_platform`, `npm_config_arch` and `npm_config_libc` environment variables) diff --git a/install/check.js b/install/check.js index a398c643..e0599e51 100644 --- a/install/check.js +++ b/install/check.js @@ -3,18 +3,27 @@ 'use strict'; -const { useGlobalLibvips, globalLibvipsVersion, log, gypRebuild } = require('../lib/libvips'); +const { useGlobalLibvips, globalLibvipsVersion, log, spawnRebuild } = require('../lib/libvips'); const buildFromSource = (msg) => { log(msg); log('Attempting to build from source via node-gyp'); try { - require('node-gyp'); + require('node-addon-api'); + log('Found node-addon-api'); } catch (err) { - log('You might need to install node-gyp'); + log('Please add node-addon-api to your dependencies'); + return; + } + try { + const gyp = require('node-gyp'); + log(`Found node-gyp version ${gyp().version}`); + } catch (err) { + log('Please add node-gyp to your dependencies'); + return; } log('See https://sharp.pixelplumbing.com/install#building-from-source'); - const status = gypRebuild(); + const status = spawnRebuild(); if (status !== 0) { process.exit(status); } diff --git a/lib/libvips.js b/lib/libvips.js index b0dd45dd..8e51f07e 100644 --- a/lib/libvips.js +++ b/lib/libvips.js @@ -80,8 +80,8 @@ const isRosetta = () => { }; /* istanbul ignore next */ -const gypRebuild = () => - spawnSync('node-gyp rebuild', { +const spawnRebuild = () => + spawnSync('node-gyp rebuild --directory=src', { ...spawnSyncOptions, stdio: 'inherit' }).status; @@ -146,7 +146,7 @@ module.exports = { buildSharpLibvipsLibDir, runtimePlatformArch, log, - gypRebuild, + spawnRebuild, globalLibvipsVersion, pkgConfigPath, useGlobalLibvips diff --git a/lib/sharp.js b/lib/sharp.js index bc363a95..231a7829 100644 --- a/lib/sharp.js +++ b/lib/sharp.js @@ -14,7 +14,7 @@ const [isLinux, isMacOs, isWindows] = ['linux', 'darwin', 'win32'].map(os => run /* istanbul ignore next */ try { // Check for local build - module.exports = require(`../build/Release/sharp-${runtimePlatform}.node`); + module.exports = require(`../src/build/Release/sharp-${runtimePlatform}.node`); } catch (errLocal) { try { // Check for runtime package diff --git a/npm/from-local-build.js b/npm/from-local-build.js index c53713e6..ad7593ec 100644 --- a/npm/from-local-build.js +++ b/npm/from-local-build.js @@ -14,7 +14,7 @@ const platform = buildPlatformArch(); const dest = path.join(__dirname, platform); // Use same config as prebuild to copy binary files -const release = path.join(__dirname, '..', 'build', 'Release'); +const release = path.join(__dirname, '..', 'src', 'build', 'Release'); const prebuildrc = JSON.parse(fs.readFileSync(path.join(__dirname, '..', '.prebuildrc'), 'utf8')); const include = new RegExp(prebuildrc['include-regex'], 'i'); fs.cpSync(release, path.join(dest, 'lib'), { diff --git a/package.json b/package.json index ed05f09b..d9078ee6 100644 --- a/package.json +++ b/package.json @@ -90,7 +90,7 @@ ], "scripts": { "install": "node install/check", - "clean": "rm -rf build/ .nyc_output/ coverage/ test/fixtures/output.*", + "clean": "rm -rf src/build/ .nyc_output/ coverage/ test/fixtures/output.*", "test": "npm run test-lint && npm run test-unit && npm run test-licensing && npm run test-types", "test-lint": "semistandard && cpplint", "test-unit": "nyc --reporter=lcov --reporter=text --check-coverage --branches=100 mocha", @@ -107,10 +107,9 @@ "main": "lib/index.js", "types": "lib/index.d.ts", "files": [ - "binding.gyp", "install", "lib", - "src" + "src/*.{cc,h,gyp}" ], "repository": { "type": "git", @@ -137,7 +136,6 @@ "dependencies": { "color": "^4.2.3", "detect-libc": "^2.0.2", - "node-addon-api": "^7.0.0", "semver": "^7.5.4" }, "optionalDependencies": { @@ -171,6 +169,7 @@ "jsdoc-to-markdown": "^8.0.0", "license-checker": "^25.0.1", "mocha": "^10.2.0", + "node-addon-api": "^7.0.0", "nyc": "^15.1.0", "prebuild": "^12.1.0", "semistandard": "^17.0.0", diff --git a/binding.gyp b/src/binding.gyp similarity index 90% rename from binding.gyp rename to src/binding.gyp index a2d408e3..25fe4083 100644 --- a/binding.gyp +++ b/src/binding.gyp @@ -3,11 +3,11 @@ { 'variables': { - 'vips_version': '