From 42e92dcb5708bb85edc64719006e0ce2b413898d Mon Sep 17 00:00:00 2001 From: "Wu, Zhenyu" Date: Tue, 14 Jan 2025 00:22:38 +0800 Subject: [PATCH] :white_check_mark: Add example for npm package --- .gitignore | 1 + .pre-commit-config.yaml | 9 ++++++++ README.md | 5 +++- examples/nodejs/1_hello_world/README.md | 17 ++++++++++++++ examples/nodejs/1_hello_world/napi/hello.c | 23 +++++++++++++++++++ examples/nodejs/1_hello_world/napi/hello.js | 3 +++ .../nodejs/1_hello_world/napi/package.json | 15 ++++++++++++ examples/nodejs/1_hello_world/napi/xmake.lua | 12 ++++++++++ .../node-addon-api-addon-class/hello.cc | 16 +++++++++++++ .../node-addon-api-addon-class/hello.js | 3 +++ .../node-addon-api-addon-class/package.json | 15 ++++++++++++ .../node-addon-api-addon-class/xmake.lua | 12 ++++++++++ .../1_hello_world/node-addon-api/hello.cc | 14 +++++++++++ .../1_hello_world/node-addon-api/hello.js | 3 +++ .../1_hello_world/node-addon-api/package.json | 15 ++++++++++++ .../1_hello_world/node-addon-api/xmake.lua | 12 ++++++++++ package.json | 3 ++- scripts/test.sh | 11 +++++++++ shell.nix | 4 ++++ 19 files changed, 191 insertions(+), 2 deletions(-) create mode 100644 examples/nodejs/1_hello_world/README.md create mode 100644 examples/nodejs/1_hello_world/napi/hello.c create mode 100644 examples/nodejs/1_hello_world/napi/hello.js create mode 100644 examples/nodejs/1_hello_world/napi/package.json create mode 100644 examples/nodejs/1_hello_world/napi/xmake.lua create mode 100644 examples/nodejs/1_hello_world/node-addon-api-addon-class/hello.cc create mode 100644 examples/nodejs/1_hello_world/node-addon-api-addon-class/hello.js create mode 100644 examples/nodejs/1_hello_world/node-addon-api-addon-class/package.json create mode 100644 examples/nodejs/1_hello_world/node-addon-api-addon-class/xmake.lua create mode 100644 examples/nodejs/1_hello_world/node-addon-api/hello.cc create mode 100644 examples/nodejs/1_hello_world/node-addon-api/hello.js create mode 100644 examples/nodejs/1_hello_world/node-addon-api/package.json create mode 100644 examples/nodejs/1_hello_world/node-addon-api/xmake.lua create mode 100755 scripts/test.sh diff --git a/.gitignore b/.gitignore index 6389b97..95ac8cf 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +.xmake/ /prebuilds/ *.tar.gz /xmake-*/ diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 0de0394..690e1b4 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -46,6 +46,10 @@ repos: rev: 3.0.0 hooks: - id: check-mailmap + # https://github.com/koalaman/shellcheck/issues/2909 + - id: shellcheck + exclude_types: + - zsh - repo: https://github.com/rhysd/actionlint rev: v1.7.5 hooks: @@ -78,6 +82,10 @@ repos: rev: "20240903.09" hooks: - id: perltidy + - repo: https://github.com/scop/pre-commit-shfmt + rev: v3.10.0-2 + hooks: + - id: shfmt - repo: https://github.com/astral-sh/ruff-pre-commit rev: v0.8.4 hooks: @@ -98,4 +106,5 @@ repos: ci: skip: + - shellcheck - pyright diff --git a/README.md b/README.md index b3047b4..3eff652 100644 --- a/README.md +++ b/README.md @@ -51,7 +51,10 @@ Compared to other solutions: examples: -- [coc-rime](https://github.com/tonyfettes/coc-rime) +- [1_hello_world](examples/nodejs/1_hello_world) +- [coc-rime](https://github.com/tonyfettes/coc-rime): use + [pkg-prebuilds](https://github.com/julusian/pkg-prebuilds) to replace + [node-gyp-build](https://github.com/prebuild/node-gyp-build) ## [luarocks.org](https://luarocks.org/modules/Freed-Wu/xmake/) diff --git a/examples/nodejs/1_hello_world/README.md b/examples/nodejs/1_hello_world/README.md new file mode 100644 index 0000000..89ef96d --- /dev/null +++ b/examples/nodejs/1_hello_world/README.md @@ -0,0 +1,17 @@ +# Example + +Modified from + + +**NOTE**: Don't support nan because + +and node_version.h is missing. + +## Example 1: *Hello world* + +To get started let's make a small addon which is the C++ equivalent of +the following JavaScript code: + +```js +module.exports.hello = function() { return 'world'; }; +``` diff --git a/examples/nodejs/1_hello_world/napi/hello.c b/examples/nodejs/1_hello_world/napi/hello.c new file mode 100644 index 0000000..19207c8 --- /dev/null +++ b/examples/nodejs/1_hello_world/napi/hello.c @@ -0,0 +1,23 @@ +#include +#include + +static napi_value Method(napi_env env, napi_callback_info info) { + napi_status status; + napi_value world; + status = napi_create_string_utf8(env, "world", 5, &world); + assert(status == napi_ok); + return world; +} + +#define DECLARE_NAPI_METHOD(name, func) \ + { name, 0, func, 0, 0, 0, napi_default, 0 } + +static napi_value Init(napi_env env, napi_value exports) { + napi_status status; + napi_property_descriptor desc = DECLARE_NAPI_METHOD("hello", Method); + status = napi_define_properties(env, exports, 1, &desc); + assert(status == napi_ok); + return exports; +} + +NAPI_MODULE(NODE_GYP_MODULE_NAME, Init) diff --git a/examples/nodejs/1_hello_world/napi/hello.js b/examples/nodejs/1_hello_world/napi/hello.js new file mode 100644 index 0000000..5557003 --- /dev/null +++ b/examples/nodejs/1_hello_world/napi/hello.js @@ -0,0 +1,3 @@ +var addon = require('bindings')('hello'); + +console.log(addon.hello()); // 'world' diff --git a/examples/nodejs/1_hello_world/napi/package.json b/examples/nodejs/1_hello_world/napi/package.json new file mode 100644 index 0000000..4917d42 --- /dev/null +++ b/examples/nodejs/1_hello_world/napi/package.json @@ -0,0 +1,15 @@ +{ + "name": "hello_world", + "version": "0.0.0", + "description": "Node.js Addons Example #1", + "main": "hello.js", + "private": true, + "dependencies": { + "xmake-build-system": "^2.9.7", + "bindings": "~1.5.0" + }, + "scripts": { + "prepack": "xmake -y && xmake install", + "test": "node hello.js" + } +} diff --git a/examples/nodejs/1_hello_world/napi/xmake.lua b/examples/nodejs/1_hello_world/napi/xmake.lua new file mode 100644 index 0000000..2a76038 --- /dev/null +++ b/examples/nodejs/1_hello_world/napi/xmake.lua @@ -0,0 +1,12 @@ +-- luacheck: ignore 113 143 +---@diagnostic disable: undefined-global +add_rules("mode.debug", "mode.release") + +add_requires("node-api-headers") + +target("hello") +do + add_rules("nodejs.module") + add_packages("node-api-headers") + add_files("*.c") +end diff --git a/examples/nodejs/1_hello_world/node-addon-api-addon-class/hello.cc b/examples/nodejs/1_hello_world/node-addon-api-addon-class/hello.cc new file mode 100644 index 0000000..549ea1f --- /dev/null +++ b/examples/nodejs/1_hello_world/node-addon-api-addon-class/hello.cc @@ -0,0 +1,16 @@ +#include + +class HelloAddon : public Napi::Addon { + public: + HelloAddon(Napi::Env env, Napi::Object exports) { + DefineAddon(exports, + {InstanceMethod("hello", &HelloAddon::Hello, napi_enumerable)}); + } + + private: + Napi::Value Hello(const Napi::CallbackInfo& info) { + return Napi::String::New(info.Env(), "world"); + } +}; + +NODE_API_ADDON(HelloAddon) diff --git a/examples/nodejs/1_hello_world/node-addon-api-addon-class/hello.js b/examples/nodejs/1_hello_world/node-addon-api-addon-class/hello.js new file mode 100644 index 0000000..5557003 --- /dev/null +++ b/examples/nodejs/1_hello_world/node-addon-api-addon-class/hello.js @@ -0,0 +1,3 @@ +var addon = require('bindings')('hello'); + +console.log(addon.hello()); // 'world' diff --git a/examples/nodejs/1_hello_world/node-addon-api-addon-class/package.json b/examples/nodejs/1_hello_world/node-addon-api-addon-class/package.json new file mode 100644 index 0000000..4917d42 --- /dev/null +++ b/examples/nodejs/1_hello_world/node-addon-api-addon-class/package.json @@ -0,0 +1,15 @@ +{ + "name": "hello_world", + "version": "0.0.0", + "description": "Node.js Addons Example #1", + "main": "hello.js", + "private": true, + "dependencies": { + "xmake-build-system": "^2.9.7", + "bindings": "~1.5.0" + }, + "scripts": { + "prepack": "xmake -y && xmake install", + "test": "node hello.js" + } +} diff --git a/examples/nodejs/1_hello_world/node-addon-api-addon-class/xmake.lua b/examples/nodejs/1_hello_world/node-addon-api-addon-class/xmake.lua new file mode 100644 index 0000000..94799e9 --- /dev/null +++ b/examples/nodejs/1_hello_world/node-addon-api-addon-class/xmake.lua @@ -0,0 +1,12 @@ +-- luacheck: ignore 113 143 +---@diagnostic disable: undefined-global +add_rules("mode.debug", "mode.release") + +add_requires("node-addon-api") + +target("hello") +do + add_rules("nodejs.module") + add_packages("node-addon-api") + add_files("*.cc") +end diff --git a/examples/nodejs/1_hello_world/node-addon-api/hello.cc b/examples/nodejs/1_hello_world/node-addon-api/hello.cc new file mode 100644 index 0000000..0957f53 --- /dev/null +++ b/examples/nodejs/1_hello_world/node-addon-api/hello.cc @@ -0,0 +1,14 @@ +#include + +Napi::String Method(const Napi::CallbackInfo& info) { + Napi::Env env = info.Env(); + return Napi::String::New(env, "world"); +} + +Napi::Object Init(Napi::Env env, Napi::Object exports) { + exports.Set(Napi::String::New(env, "hello"), + Napi::Function::New(env, Method)); + return exports; +} + +NODE_API_MODULE(hello, Init) diff --git a/examples/nodejs/1_hello_world/node-addon-api/hello.js b/examples/nodejs/1_hello_world/node-addon-api/hello.js new file mode 100644 index 0000000..5557003 --- /dev/null +++ b/examples/nodejs/1_hello_world/node-addon-api/hello.js @@ -0,0 +1,3 @@ +var addon = require('bindings')('hello'); + +console.log(addon.hello()); // 'world' diff --git a/examples/nodejs/1_hello_world/node-addon-api/package.json b/examples/nodejs/1_hello_world/node-addon-api/package.json new file mode 100644 index 0000000..4917d42 --- /dev/null +++ b/examples/nodejs/1_hello_world/node-addon-api/package.json @@ -0,0 +1,15 @@ +{ + "name": "hello_world", + "version": "0.0.0", + "description": "Node.js Addons Example #1", + "main": "hello.js", + "private": true, + "dependencies": { + "xmake-build-system": "^2.9.7", + "bindings": "~1.5.0" + }, + "scripts": { + "prepack": "xmake -y && xmake install", + "test": "node hello.js" + } +} diff --git a/examples/nodejs/1_hello_world/node-addon-api/xmake.lua b/examples/nodejs/1_hello_world/node-addon-api/xmake.lua new file mode 100644 index 0000000..94799e9 --- /dev/null +++ b/examples/nodejs/1_hello_world/node-addon-api/xmake.lua @@ -0,0 +1,12 @@ +-- luacheck: ignore 113 143 +---@diagnostic disable: undefined-global +add_rules("mode.debug", "mode.release") + +add_requires("node-addon-api") + +target("hello") +do + add_rules("nodejs.module") + add_packages("node-addon-api") + add_files("*.cc") +end diff --git a/package.json b/package.json index 6707237..8e7444f 100644 --- a/package.json +++ b/package.json @@ -17,6 +17,7 @@ "tar": "^7.4.3" }, "scripts": { - "prepack": "node scripts/build.cjs" + "prepack": "node scripts/build.cjs", + "test": "scripts/test.sh" } } diff --git a/scripts/test.sh b/scripts/test.sh new file mode 100755 index 0000000..d7ab39d --- /dev/null +++ b/scripts/test.sh @@ -0,0 +1,11 @@ +#!/usr/bin/env bash +set -e +cd "$(dirname "$(dirname "$(readlink -f "$0")")")" + +cd examples/nodejs/1_hello_world +for dir in ./*/; do + cd "$dir" + npm install + npm run prepack + npm test +done diff --git a/shell.nix b/shell.nix index c0e5f79..a7311d1 100644 --- a/shell.nix +++ b/shell.nix @@ -19,4 +19,8 @@ mkShell { ] )) ]; + # https://github.com/NixOS/nixpkgs/issues/314313#issuecomment-2134252094 + shellHook = '' + LD="$CC" + ''; }