From 5e3a6d9fe592f0e6654571ab97560a85a8d83a96 Mon Sep 17 00:00:00 2001 From: Devraj Mehta Date: Tue, 13 Jun 2023 10:04:42 -0400 Subject: [PATCH 1/6] Add path for platform/arch without node version --- bindings.js | 1 + 1 file changed, 1 insertion(+) diff --git a/bindings.js b/bindings.js index 226b37f..493d0ac 100644 --- a/bindings.js +++ b/bindings.js @@ -49,6 +49,7 @@ var fs = require('fs'), ['module_root', 'build', 'default', 'bindings'], // Production "Release" buildtype binary (meh...) ['module_root', 'compiled', 'version', 'platform', 'arch', 'bindings'], + ['module_root', 'compiled', 'platform', 'arch', 'bindings'], // node-qbs builds ['module_root', 'addon-build', 'release', 'install-root', 'bindings'], ['module_root', 'addon-build', 'debug', 'install-root', 'bindings'], From 4840915737a64a528162de46be930ba4ce4c1847 Mon Sep 17 00:00:00 2001 From: Devraj Mehta Date: Tue, 13 Jun 2023 15:59:53 -0400 Subject: [PATCH 2/6] Put dummy into Error to prevent Webpack removal --- bindings.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bindings.js b/bindings.js index 493d0ac..6646f7f 100644 --- a/bindings.js +++ b/bindings.js @@ -170,7 +170,7 @@ exports.getFileName = function getFileName(calling_file) { // run the 'prepareStackTrace' function above Error.captureStackTrace(dummy); - dummy.stack; + new Error(dummy.stack); // cleanup Error.prepareStackTrace = origPST; From fd9442fe9faef6d300005f4e6a1e786992ac0d8f Mon Sep 17 00:00:00 2001 From: Devraj Mehta Date: Fri, 7 Jul 2023 15:12:57 -0400 Subject: [PATCH 3/6] Use __filename instead of using an error trace This more or less assumes a rollup build, e.g. webpack --- bindings.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/bindings.js b/bindings.js index 6646f7f..3bf8259 100644 --- a/bindings.js +++ b/bindings.js @@ -80,7 +80,10 @@ function bindings(opts) { // Get the module root if (!opts.module_root) { - opts.module_root = exports.getRoot(exports.getFileName()); + // Instead of using an error trace to find the calling file: + // opts.module_root = exports.getRoot(exports.getFileName()); + // Use the webpack __filename: + opts.module_root = exports.getRoot(__filename); } // Ensure the given bindings name ends with .node From 6b57e6883b34dbb6942467a7e49afce99d9d6832 Mon Sep 17 00:00:00 2001 From: Devraj Mehta Date: Mon, 10 Jul 2023 13:04:08 -0400 Subject: [PATCH 4/6] Skip walking the directories to find the root Since we are assuming a webpack rollup build the root directory should be the current directory. --- bindings.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bindings.js b/bindings.js index 3bf8259..28afeec 100644 --- a/bindings.js +++ b/bindings.js @@ -82,8 +82,8 @@ function bindings(opts) { if (!opts.module_root) { // Instead of using an error trace to find the calling file: // opts.module_root = exports.getRoot(exports.getFileName()); - // Use the webpack __filename: - opts.module_root = exports.getRoot(__filename); + // Use the webpack __filename as the root directory: + opts.module_root = dirname(__filename); } // Ensure the given bindings name ends with .node From 7799edacc94f445e8eee8859bba565bea9eba4fd Mon Sep 17 00:00:00 2001 From: Devraj Mehta Date: Fri, 6 Dec 2024 13:46:17 -0500 Subject: [PATCH 5/6] Update to tailor to the forked use-case and publish to npm --- README.md | 106 +++++++-------------------------------------------- bindings.js | 84 ++++++---------------------------------- package.json | 14 +++---- 3 files changed, 29 insertions(+), 175 deletions(-) diff --git a/README.md b/README.md index 5b3e7a8..28395bf 100644 --- a/README.md +++ b/README.md @@ -1,98 +1,18 @@ -node-bindings +[@devm33/bindings](https://www.npmjs.com/package/@devm33/bindings) ============= -### Helper module for loading your native module's `.node` file -This is a helper module for authors of Node.js native addon modules. -It is basically the "swiss army knife" of `require()`ing your native module's -`.node` file. +Fork of [node-bindings](https://github.com/TooTallNate/node-bindings), +re-purposed for use in a bundled environment. -Throughout the course of Node's native addon history, addons have ended up being -compiled in a variety of different places, depending on which build tool and which -version of node was used. To make matters worse, now the `gyp` build tool can -produce either a __Release__ or __Debug__ build, each being built into different -locations. +The original node-bindings attempts to load native addons by walking a series of +known paths relative to the executing file's `node_modules` folder. This doesn't +work well for a bundled use case where there is no `node_modules` folder and the +native addons need to be placed alongside the bundled file. -This module checks _all_ the possible locations that a native addon would be built -at, and returns the first one that loads successfully. +The approach used by this fork is to look for the native addons where the build +process places them. The goal is to support loading modules both in an bundled +case and in a non-bundled case. - -Installation ------------- - -Install with `npm`: - -``` bash -$ npm install --save bindings -``` - -Or add it to the `"dependencies"` section of your `package.json` file. - - -Example -------- - -`require()`ing the proper bindings file for the current node version, platform -and architecture is as simple as: - -``` js -var bindings = require('bindings')('binding.node') - -// Use your bindings defined in your C files -bindings.your_c_function() -``` - - -Nice Error Output ------------------ - -When the `.node` file could not be loaded, `node-bindings` throws an Error with -a nice error message telling you exactly what was tried. You can also check the -`err.tries` Array property. - -``` -Error: Could not load the bindings file. Tried: - → /Users/nrajlich/ref/build/binding.node - → /Users/nrajlich/ref/build/Debug/binding.node - → /Users/nrajlich/ref/build/Release/binding.node - → /Users/nrajlich/ref/out/Debug/binding.node - → /Users/nrajlich/ref/Debug/binding.node - → /Users/nrajlich/ref/out/Release/binding.node - → /Users/nrajlich/ref/Release/binding.node - → /Users/nrajlich/ref/build/default/binding.node - → /Users/nrajlich/ref/compiled/0.8.2/darwin/x64/binding.node - at bindings (/Users/nrajlich/ref/node_modules/bindings/bindings.js:84:13) - at Object. (/Users/nrajlich/ref/lib/ref.js:5:47) - at Module._compile (module.js:449:26) - at Object.Module._extensions..js (module.js:467:10) - at Module.load (module.js:356:32) - at Function.Module._load (module.js:312:12) - ... -``` - -The searching for the `.node` file will originate from the first directory in which has a `package.json` file is found. - -License -------- - -(The MIT License) - -Copyright (c) 2012 Nathan Rajlich <nathan@tootallnate.net> - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -'Software'), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +The bundled case is determined by looking for a neighboring `compiled` +directory. The non-bundled case is determined by looking for a `dist/compiled` +when walking up the filesystem from the current file. \ No newline at end of file diff --git a/bindings.js b/bindings.js index 28afeec..97002d8 100644 --- a/bindings.js +++ b/bindings.js @@ -4,7 +4,6 @@ var fs = require('fs'), path = require('path'), - fileURLToPath = require('file-uri-to-path'), join = path.join, dirname = path.dirname, exists = @@ -50,21 +49,12 @@ var fs = require('fs'), // Production "Release" buildtype binary (meh...) ['module_root', 'compiled', 'version', 'platform', 'arch', 'bindings'], ['module_root', 'compiled', 'platform', 'arch', 'bindings'], - // node-qbs builds - ['module_root', 'addon-build', 'release', 'install-root', 'bindings'], - ['module_root', 'addon-build', 'debug', 'install-root', 'bindings'], - ['module_root', 'addon-build', 'default', 'install-root', 'bindings'], - // node-pre-gyp path ./lib/binding/{node_abi}-{platform}-{arch} - ['module_root', 'lib', 'binding', 'nodePreGyp', 'bindings'] ] }; /** * The main `bindings()` function loads the compiled bindings for a given module. - * It uses V8's Error API to determine the parent filename that this function is - * being invoked from, which is then used to find the root directory. */ - function bindings(opts) { // Argument surgery if (typeof opts == 'string') { @@ -80,10 +70,7 @@ function bindings(opts) { // Get the module root if (!opts.module_root) { - // Instead of using an error trace to find the calling file: - // opts.module_root = exports.getRoot(exports.getFileName()); - // Use the webpack __filename as the root directory: - opts.module_root = dirname(__filename); + opts.module_root = getRoot(__filename); } // Ensure the given bindings name ends with .node @@ -140,64 +127,14 @@ function bindings(opts) { err.tries = tries; throw err; } -module.exports = exports = bindings; - -/** - * Gets the filename of the JavaScript file that invokes this function. - * Used to help find the root directory of a module. - * Optionally accepts an filename argument to skip when searching for the invoking filename - */ - -exports.getFileName = function getFileName(calling_file) { - var origPST = Error.prepareStackTrace, - origSTL = Error.stackTraceLimit, - dummy = {}, - fileName; - - Error.stackTraceLimit = 10; - - Error.prepareStackTrace = function(e, st) { - for (var i = 0, l = st.length; i < l; i++) { - fileName = st[i].getFileName(); - if (fileName !== __filename) { - if (calling_file) { - if (fileName !== calling_file) { - return; - } - } else { - return; - } - } - } - }; - - // run the 'prepareStackTrace' function above - Error.captureStackTrace(dummy); - new Error(dummy.stack); - - // cleanup - Error.prepareStackTrace = origPST; - Error.stackTraceLimit = origSTL; - - // handle filename that starts with "file://" - var fileSchema = 'file://'; - if (fileName.indexOf(fileSchema) === 0) { - fileName = fileURLToPath(fileName); - } - - return fileName; -}; +module.exports = bindings; /** * Gets the root directory of a module, given an arbitrary filename * somewhere in the module tree. The "root directory" is the directory - * containing the `package.json` file. - * - * In: /home/nate/node-native-module/lib/index.js - * Out: /home/nate/node-native-module + * containing either a 'dist' or a 'compiled' directory. */ - -exports.getRoot = function getRoot(file) { +function getRoot(file) { var dir = dirname(file), prev; while (true) { @@ -205,11 +142,12 @@ exports.getRoot = function getRoot(file) { // Avoids an infinite loop in rare cases, like the REPL dir = process.cwd(); } - if ( - exists(join(dir, 'package.json')) || - exists(join(dir, 'node_modules')) - ) { - // Found the 'package.json' file or 'node_modules' dir; we're done + if (exists(join(dir, 'dist'))) { + // Found the 'dist' dir; step into it and done + return join(dir, 'dist'); + } + if (exists(join(dir, 'compiled'))) { + // Found the 'compiled' dir; we're done return dir; } if (prev === dir) { @@ -217,7 +155,7 @@ exports.getRoot = function getRoot(file) { throw new Error( 'Could not find module root given file: "' + file + - '". Do you have a `package.json` file? ' + '". Do you have a `dist` or `compiled` directory? ' ); } // Try the parent dir next diff --git a/package.json b/package.json index d027ee7..4c5b418 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "name": "bindings", + "name": "@devm33/bindings", "description": "Helper module for loading your native module's .node file", "keywords": [ "native", @@ -11,18 +11,14 @@ "c++" ], "version": "1.5.0", - "author": "Nathan Rajlich (http://tootallnate.net)", "repository": { "type": "git", - "url": "git://github.com/TooTallNate/node-bindings.git" + "url": "git://github.com/devm33/node-bindings.git" }, "main": "./bindings.js", "bugs": { - "url": "https://github.com/TooTallNate/node-bindings/issues" + "url": "https://github.com/devm33/node-bindings/issues" }, - "homepage": "https://github.com/TooTallNate/node-bindings", - "license": "MIT", - "dependencies": { - "file-uri-to-path": "1.0.0" - } + "homepage": "https://github.com/devm33/node-bindings", + "license": "MIT" } From c270b5527d1b97ed2484cd53badfad469aea3c06 Mon Sep 17 00:00:00 2001 From: Devraj Mehta Date: Fri, 6 Dec 2024 13:51:33 -0500 Subject: [PATCH 6/6] Remove scope from package name --- README.md | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 28395bf..1faaaac 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -[@devm33/bindings](https://www.npmjs.com/package/@devm33/bindings) +[bundled-bindings](https://www.npmjs.com/package/bundled-bindings) ============= Fork of [node-bindings](https://github.com/TooTallNate/node-bindings), diff --git a/package.json b/package.json index 4c5b418..bd0d6c2 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "name": "@devm33/bindings", + "name": "bundled-bindings", "description": "Helper module for loading your native module's .node file", "keywords": [ "native",