Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Restart (rs) and the Webpack plugin do not work with a native module #3052

Closed
3 tasks done
cwellsx opened this issue Nov 5, 2022 · 6 comments
Closed
3 tasks done
Labels
blocked/needs-info Issues lacking information for resolution bug plugin/webpack Issues or pull requests related to first-party webpack plugins/templates

Comments

@cwellsx
Copy link

cwellsx commented Nov 5, 2022

Pre-flight checklist

  • I have read the contribution documentation for this project.
  • I agree to follow the code of conduct that this project uses.
  • I have searched the issue tracker for a bug that matches the one I want to file, without success.

Electron Forge version

6.0.0-beta.67

Electron version

v20.1.1

Operating system

Windows 10 Version 21H1 Build 19043.2130

Last known working Electron Forge version

No response

Expected behavior

I have better_sqlite3 included in my project, which is based on the Webpack+Typescript template.

npm start works fine, and so does npm run package -- after either of these I can access the SQLite API.

It should also work when I restart it using rs as mentioned here:

If you type rs (and hit enter) in the same terminal where you ran the start command, the running app will be terminated and restarted.

Forge plugins can override this command to run custom development logic. For example, the Webpack Plugin runs a webpack-dev-server instance to provide live reloading and HMR.

Actual behavior

I get an error message when I type rs as follows:

image

Steps to reproduce

FYI the git commit I made to include better-sqlite3 in my project is here ...

... but it was easy to do, nothing special, i.e.:

  • Install better-sqlite3 as a run-time dependency
  • Install the latest Node.js with the "Windows build tools" option enabled so that it can be built for Electron
  • Include it in the Main process using import sqlite from 'better-sqlite3';

Additional information

It finds better_sqlite3.node when it starts but not when it restarts.

The error message says it's looking for undefinedbuild/Release/better_sqlite3.node

In fact the better_sqlite3.node exists in the following directories:

C:\Users\Christopher\Source\Repos\pic>dir /s better_sqlite3.node
 Volume in drive C is Windows
 Volume Serial Number is 6EBC-4C1A

 Directory of C:\Users\Christopher\Source\Repos\pic\.webpack\main\native_modules\build\Release

05/11/2022  18:29         2,659,328 better_sqlite3.node
               1 File(s)      2,659,328 bytes

 Directory of C:\Users\Christopher\Source\Repos\pic\node_modules\better-sqlite3\build\Release

23/10/2022  09:41         2,659,328 better_sqlite3.node
               1 File(s)      2,659,328 bytes

 Directory of C:\Users\Christopher\Source\Repos\pic\out\pic-win32-x64\resources\app\.webpack\main\native_modules\build\Release

29/10/2022  09:52         2,659,328 better_sqlite3.node
               1 File(s)      2,659,328 bytes

     Total Files Listed:
               3 File(s)      7,977,984 bytes

The one which it's successfully using when it starts is presumably the one in the .webpack\main\native_modules\ directory -- and this is the path fragment that's replaced with "undefined" during a restart.

I see there are previous issues related to rs -- https://github.com/electron/forge/issues?q=rs -- but they're all close.

@VerteDinde
Copy link
Member

Hey @cwellsx, would you mind trying this with v6.0.0? I think we may have addressed this issue in a later beta version than the one you’re running, just want to make sure that’s the case.

@cwellsx
Copy link
Author

cwellsx commented Nov 7, 2022

Hi @VerteDinde thank you.
Yes, I should try with v6.0.0.
Probably next week-end (Nov, 12-13).

@erickzhao erickzhao added plugin/webpack Issues or pull requests related to first-party webpack plugins/templates bug blocked/needs-info Issues lacking information for resolution labels Nov 7, 2022
@MarshallOfSound
Copy link
Member

I tested this on latest forge (inited from template, added depedency, etc.)

Had to drop to Electron 19 because that module doesn't support Electron 20 or higher yet (WiseLibs/better-sqlite3#870) but other than that it works fine during both start, restart and package

@MarshallOfSound MarshallOfSound closed this as not planned Won't fix, can't repro, duplicate, stale Nov 9, 2022
@cwellsx
Copy link
Author

cwellsx commented Nov 20, 2022

@MarshallOfSound @VerteDinde @erickzhao

I confirm that I still have this problem, with the 6.0.0 release.

  • This loads fine -- npm start and then rs
  • But this errors -- if I edit the source code, after npm start and before rs

Also the problem doesn't occur when I import the module but when I call its sqlite function to instantiate a new database.


BTW instead of dropping the Electron version I install the pull request:

npm install WiseLibs/better-sqlite3#pull/870/head


Let me know if you want more information or anything.

@cwellsx
Copy link
Author

cwellsx commented Nov 20, 2022

The problem is this line of code:

		addon = DEFAULT_ADDON || (DEFAULT_ADDON = require('bindings')('better_sqlite3.node'));

That TypeScript statement translates to this JavaScript:

		addon = DEFAULT_ADDON || (DEFAULT_ADDON = require(__webpack_require__.ab + "build/Release/better_sqlite3.node"));

When I press rs without modifying the code, the value of __webpack_require__.ab (on my machine) is

  • 'C:\Users\Christopher\Source\Repos\pic\.webpack\main/native_modules/'

And it's undefined when I have the problem on restart.

Maybe it's related to this, because that's to do with setting the __webpack_require__.ab value:

IOW maybe the @vercel/webpack-asset-relocator-loader is not being re-run or something.

I can work-around the problem using their nativeBinding option which is described here:

if you're using a complicated build system that moves, transforms, or concatenates your JS files, better-sqlite3 might have trouble locating its native C++ addon (better_sqlite3.node). If you get an error that looks like WiseLibs/better-sqlite3#534 (comment), you can solve it by using this option to provide the file path of better_sqlite3.node (relative to the current working directory).

So for example if my code looks like this then I don't get the error:

export function createSqlDatabase(filename: string): SqlApi {
  const options: sqlite.Options = {
    nativeBinding:
      "C:\\Users\\Christopher\\Source\\Repos\\pic\\.webpack\\main\\native_modules\\build\\Release\\better_sqlite3.node",
  };
  const db = sqlite(filename, options);

That's not ideal, especially when the application is packaged (but a useful work-around to make rs work).

In summary I guess this problem related to the @vercel/webpack-asset-relocator-loader is not being re-run on restart.

@hansSchall
Copy link

Simple workaround that worked for me (same error when using @napi-rs/canvas): adding __webpack_require__.ab = __dirname + "/native_modules/"; at the very beginning of index.js (above the imports)

This reproduces the same path even if rs is used

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
blocked/needs-info Issues lacking information for resolution bug plugin/webpack Issues or pull requests related to first-party webpack plugins/templates
Projects
None yet
Development

No branches or pull requests

5 participants