With the `node-addon` I don't get any errors but the React Page doesn't show up

Đang mở
#206 0 bình luận 0 reaction 0 người được giao Xem trên GitHub

Chưa có ai nhận issue này.

Đánh giá

Độ khó
4/5
Thời gian dự kiến
3-5 ngày
Mức phù hợp với người mới
28/100
Loại issue
Lỗi
Độ rõ ràng
Khá rõ ràng
Mức độ hoạt động
Đình trệ
Công nghệ
cpp, node.js, react, typescript, webpack

Hướng nghiên cứu

Start with src/index.tsx, webpack.config.js, binding.gyp, and the emitted build/Release/greet.node while reproducing the issue with yarn start. Done means the React page loads at the dev-server URL and renders the expected “My React and TypeScript App!” header without errors.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Mô tả

Following the indications found here: https://medium.com/jspoint/a-simple-guide-to-load-c-c-code-into-node-js-javascript-applications-3fcccf54fd32 and here https://github.com/nodejs/node-addon-examples/tree/main/1_hello_world/node-addon-api
I'm trying to understand how to effectively use node-addon-api for later include within electron C++ module.

In a simple react-typescript-webpack app I've put this:

package.json :

{
  "name": "greet",
  "version": "0.0.1",
  "license": "UNLICENSED",
  "scripts": {
    "start": "webpack serve --open",
    "build": "webpack --mode production"
  },
  "dependencies": {
    "node-addon-api": "^6.0.0",
    "node-gyp": "^9.3.1",
    "react": "^18.2.0",
    "react-dom": "^18.2.0"
  },
  "devDependencies": {
    "@babel/core": "^7.20.12",
    "@babel/plugin-transform-runtime": "^7.19.6",
    "@babel/preset-env": "^7.20.2",
    "@babel/preset-react": "^7.18.6",
    "@babel/preset-typescript": "^7.18.6",
    "@babel/runtime": "^7.20.13",
    "@types/fork-ts-checker-webpack-plugin": "^0.4.5",
    "@types/react": "^18.0.28",
    "@types/react-dom": "^18.0.10",
    "@types/webpack": "^5.28.0",
    "@types/webpack-dev-server": "^4.7.2",
    "@typescript-eslint/eslint-plugin": "^5.51.0",
    "@typescript-eslint/parser": "^5.51.0",
    "babel-loader": "^9.1.2",
    "eslint": "^8.34.0",
    "eslint-plugin-react": "^7.32.2",
    "eslint-plugin-react-hooks": "^4.6.0",
    "fork-ts-checker-webpack-plugin": "^7.3.0",
    "node-loader": "^2.0.0",
    "ts-node": "^10.9.1",
    "typescript": "^4.9.5",
    "webpack": "^5.75.0",
    "webpack-cli": "^5.0.1",
    "webpack-dev-server": "^4.11.1"
  },
  "resolutions": {
    "@types/webpack": "^4.4.11"
  }
}

webpack.config.js :

const webpack = require("webpack")
const webpackDevServer = require("webpack-dev-server")
const path = require("path")
const Configuration = require("webpack")
const ForkTsCheckerWebpackPlugin = require("fork-ts-checker-webpack-plugin")

// https://webpack.js.org/loaders/node-loader/


const config: typeof Configuration = {
  entry: "./src/index.tsx",
  target: "node",
  node: {
    __dirname: false,
  },
  module: {
    rules: [
      {
        test: /\.node$/,
        use: 'node-loader',
      },
      {
        test: /\.(ts|js)x?$/,
        exclude: /node_modules/,
        use: {
          loader: "babel-loader",
          options: {
            presets: [
              "@babel/preset-env",
              "@babel/preset-react",
              "@babel/preset-typescript",
            ],
          },
        },
      },
    ],
  },
  resolve: {
    extensions: [".tsx", ".ts", ".js"],
  },
  mode: 'development',
  output: {
    path: path.resolve(__dirname, "build"),
    filename: "bundle.js",
  },
  devServer: {
    static: path.join(__dirname, "build"),
    compress: true,
    port: 4000,
  },
  plugins: [
    new ForkTsCheckerWebpackPlugin({
      async: false,
    }),
  ],
};

export default config;

tsconfig.json:

    {
      "compilerOptions": {
        "lib": ["dom", "dom.iterable", "esnext"],
        "allowJs": true,
        "allowSyntheticDefaultImports": true,
        "skipLibCheck": true,
        "esModuleInterop": true,
        "strict": true,
        "forceConsistentCasingInFileNames": true,
        "moduleResolution": "node",
        "resolveJsonModule": true,
        "isolatedModules": true,
        "noEmit": true,
        "jsx": "react"
      },
      "include": ["src"]
    }

binding.gyp :

{
  "targets": [
    {
      "target_name": "greet",
      "cflags!": [ "-fno-exceptions" ],
      "cflags_cc!": [ "-fno-exceptions" ],
      "sources": [
        "./src/greeting.cpp",
        "./src/index.cpp"
      ],
      "include_dirs": [
        "<!@(node -p \"require('node-addon-api').include\")"
      ],
      'defines': [ 'NAPI_DISABLE_CPP_EXCEPTIONS' ],
    }
  ],

  'cflags!': [ '-fno-exceptions' ],
  'cflags_cc!': [ '-fno-exceptions' ],
  'conditions': [
    ["OS=='win'", {
      "defines": [
        "_HAS_EXCEPTIONS=1"
      ],
      "msvs_settings": {
        "VCCLCompilerTool": {
          "ExceptionHandling": 1
        },
      },
    }],
    ["OS=='mac'", {
      'xcode_settings': {
        'GCC_ENABLE_CPP_EXCEPTIONS': 'YES',
        'CLANG_CXX_LIBRARY': 'libc++',
        'MACOSX_DEPLOYMENT_TARGET': '10.7',
      },
    }],
  ]

}

In ./src/ folder:

greeting.h :

#include <string>

std::string helloUser( std::string name );

greeting.cpp :

#include
#include
#include "greeting.h"

std::string helloUser( std::string name) {
    return "Hello " + name + " !";
}

int main() {

    std::string HelloUserString = helloUser("Bob");

    std::cout << HelloUserString << std::endl;

    return 0;
}

Compiling and testing the .cpp file:

raphy@raohy:~/native-greet-module/src$ g++ -std=c++20 greeting.cpp -o greeting
raphy@raohy:~/native-greet-module/src$ ./greeting 
Hello Bob !

index.cpp :

#include <napi.h>
#include <string>

// https://github.com/nodejs/node-addon-examples/blob/main/1_hello_world/node-addon-api/hello.cc

// native C++ function that is assigned to "greetHello" property on "exports" object

Napi::String greetHello(const Napi::CallbackInfo& info) {
    Napi::Env env = info.Env();

    // call "helloUser" function from "greeting.cpp" file
    // WARNING: We are passing hardcoded "MIKE" value for now
    std::string result = helloUser( "MIKE" );

    // return new "Nap::String" value
    return Napi::String::New(env, result);
}

// callback method when module is registered with Node.js
Napi::Object Init(Napi::Env env, Napi::Object exports) {

    // set a key on "exports" object
    exports.Set(
        Napi::String::New(env, "greetHello"), // property name => "greetHello"
        Napi::Function::New(env, greetHello) // property value => "greetHello" function
    );

    // return "exports" object (always)
    return exports;
}

// register "greet" module which calls "Init" method
NODE_API_MODULE(greet, Init)

I executed node-gyp configure :

raphy@raohy:~/native-greet-module$ node-gyp configure
gyp info it worked if it ends with ok
gyp info using node-gyp@9.3.0
gyp info using node@18.12.1 | linux | x64
gyp info find Python using Python version 3.10.6 found at "/usr/bin/python3"
gyp info spawn /usr/bin/python3
gyp info spawn args [
gyp info spawn args   '/home/raphy/.nvm/versions/node/v18.12.1/lib/node_modules/node-gyp/gyp/gyp_main.py',
gyp info spawn args   'binding.gyp',
gyp info spawn args   '-f',
gyp info spawn args   'make',
gyp info spawn args   '-I',
gyp info spawn args   '/home/raphy/native-greet-module/build/config.gypi',
gyp info spawn args   '-I',
gyp info spawn args   '/home/raphy/.nvm/versions/node/v18.12.1/lib/node_modules/node-gyp/addon.gypi',
gyp info spawn args   '-I',
gyp info spawn args   '/home/raphy/.cache/node-gyp/18.12.1/include/node/common.gypi',
gyp info spawn args   '-Dlibrary=shared_library',
gyp info spawn args   '-Dvisibility=default',
gyp info spawn args   '-Dnode_root_dir=/home/raphy/.cache/node-gyp/18.12.1',
gyp info spawn args   '-Dnode_gyp_dir=/home/raphy/.nvm/versions/node/v18.12.1/lib/node_modules/node-gyp',
gyp info spawn args   '-Dnode_lib_file=/home/raphy/.cache/node-gyp/18.12.1/<(target_arch)/node.lib',
gyp info spawn args   '-Dmodule_root_dir=/home/raphy/native-greet-module',
gyp info spawn args   '-Dnode_engine=v8',
gyp info spawn args   '--depth=.',
gyp info spawn args   '--no-parallel',
gyp info spawn args   '--generator-output',
gyp info spawn args   'build',
gyp info spawn args   '-Goutput_dir=.'
gyp info spawn args ]
gyp info ok 
raphy@raohy:~/native-greet-module$ 

And then node-gyp build :

raphy@raohy:~/native-greet-module$ node-gyp build
gyp info it worked if it ends with ok
gyp info using node-gyp@9.3.0
gyp info using node@18.12.1 | linux | x64
gyp info spawn make
gyp info spawn args [ 'BUILDTYPE=Release', '-C', 'build' ]
make: Entering directory '/home/raphy/native-greet-module/build'
  CXX(target) Release/obj.target/greet/src/greeting.o
  CXX(target) Release/obj.target/greet/src/index.o
  SOLINK_MODULE(target) Release/obj.target/greet.node
  COPY Release/greet.node
make: Leaving directory '/home/raphy/native-greet-module/build'
gyp info ok 
raphy@raohy:~/native-greet-module$ 

In ./src/ folder` :

index.tsx :

import React from "react";
import ReactDOM from "react-dom";

const greetModule = require('../build/Release/greet.node')

const App = () => (
  <h1>My React and TypeScript App!</h1>
);

ReactDOM.render(
  <App />,
  document.getElementById("root")
);

Starting the react app I get no errors:

raphy@raohy:~/native-greet-module$ yarn start
yarn run v1.22.19
$ webpack serve --open
<i> [webpack-dev-server] Project is running at:
<i> [webpack-dev-server] Loopback: http://localhost:4000/
<i> [webpack-dev-server] On Your Network (IPv4): http://192.168.1.7:4000/
<i> [webpack-dev-server] On Your Network (IPv6): http://[fe80::f2e3:be71:cd02:bb1d]:4000/
<i> [webpack-dev-server] Content not from webpack is served from '/home/raphy/native-greet-module/build' directory
<i> [webpack-dev-middleware] wait until bundle finished: /
asset bundle.js 1.16 MiB [emitted] (name: main)
asset 5951ea98b41e9eadb7f0d975f38f4ae6.node 60.8 KiB [emitted] (auxiliary name: main)
runtime modules 23.7 KiB 11 modules
built modules 1.09 MiB [built]
  modules by path ./node_modules/ 1.09 MiB
    modules by path ./node_modules/webpack/hot/*.js 4.59 KiB 4 modules
    modules by path ./node_modules/react/ 85.7 KiB 2 modules
    modules by path ./node_modules/react-dom/ 1000 KiB 2 modules
    modules by path ./node_modules/scheduler/ 17.3 KiB
      ./node_modules/scheduler/index.js 198 bytes [built] [code generated]
      ./node_modules/scheduler/cjs/scheduler.development.js 17.1 KiB [built] [code generated]
  ./src/index.tsx 331 bytes [built] [code generated]
  ./build/Release/greet.node 199 bytes [built] [code generated]
  external "events" 42 bytes [built] [code generated]
  external "path" 42 bytes [optional] [built] [code generated]
webpack 5.75.0 compiled successfully in 1766 ms

But I get this output, instead of the expected header message My React and TypeScript App! :

image

You can find the code in this Repo : https://github.com/raphael10-collab/native-greet-module

What's wrong with my settings? And how to make this simple React-Typescript-Webpack with node-addon showing the react page ?

Ngôn ngữ chính
C++
Star
2.6k
Fork
602
Chỉ số merge pull request
Không có pull request nào được merge trong 30 ngày

Hướng dẫn đóng góp

Mở hướng dẫn đóng góp

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Issue khác của nodejs/node-addon-examples

Tất cả issue của nodejs/node-addon-examples

Issue tương tự

Thêm issue về C++

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.