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

Rebuilding native modules #756

Closed
rgbkrk opened this issue Oct 11, 2016 · 31 comments
Closed

Rebuilding native modules #756

rgbkrk opened this issue Oct 11, 2016 · 31 comments

Comments

@rgbkrk
Copy link

rgbkrk commented Oct 11, 2016

Do you want to request a feature or report a bug?

Feature!

What is the current behavior?

https://yarnpkg.com/en/docs/migrating-from-npm does not list a way to rebuild.

What is the expected behavior?

We (in nteract) end up needing to rebuild one native module, zeromq. Normally we run this:

npm rebuild zeromq --runtime=electron --target=1.4.5 --disturl=https://atom.io/download/atom-shell --build-from-source

Our use case is specifically with Electron; I'm guessing there are others that use npm rebuild.

Please mention your node.js, yarn and operating system version.

$ node --version
v6.7.0
$ yarn --version
0.15.1

OS X 10.11.6

/cc @jdetle @captainsafia @lgeiger

@rgbkrk
Copy link
Author

rgbkrk commented Oct 11, 2016

❤️ the experience here, thank you for shaving off so many edges to make developer experience wonderful!

@rgbkrk rgbkrk changed the title Rebuilding native modules for Electron apps Rebuilding native modules Oct 12, 2016
@rgbkrk
Copy link
Author

rgbkrk commented Oct 12, 2016

Looks like we can always run the rebuild directly (even scripting it like we do to match the Electron version in our package.json). However, running yarn again after will write over the native modules that were built for Electron, resulting in an ABI mismatch.

@gaelollivier
Copy link

I would also like to have an equivalent to npm rebuild to be able to just extract a .tgz of my dependencies and rebuild the platform-specific stuff without having to re-fetch the packages. The main usage for this is building our app in Docker containers during CI. We currently can't use yarn for this use case.

@ConorIA
Copy link

ConorIA commented Nov 3, 2016

electron-builder can't support yarn without a rebuild command that respects the architecture set in the environment. Does yarn install use only the real arch of the machine, or does it build for the arch specified in the environment?

@develar
Copy link

develar commented Nov 3, 2016

Clarification to @ConorIA question: electron-builder set npm_config_arch https://github.com/electron-userland/electron-builder/blob/master/src/util/util.ts#L29 The problem is that npm_config_arch=ia32 npm installl will install and build dependencies for ia32 (if no installed modules or not yet build), but subsequent npm_config_arch=x64 npm installl will not do rebuild dependencies for specified arch. Explicit npm rebuild is required.

@develar
Copy link

develar commented Nov 8, 2016

rebuild will be implemented on electron-builder side. For any project structure (not only 2-package.json). npm rebuild doesn't support rebuild only production deps (npm/npm#5952). As electron-builder should continue to support npm (warning that yarn is recommended will be added soon) and due to the fact that rebuild is specific for Electron, it is not implemented as PR here (in any case, implementation is very simple and no need to complicate yarn).

@develar
Copy link

develar commented Nov 8, 2016

@rgbkrk It seems you can just use yarn add zmq-prebuilt --force --runtime=electron --target=1.4.3 --disturl=https://atom.io/download/atom-shell --build-from-source

--force here to force rebuild.

So, I guess, this issue can be closed (of course, no doubt, I don't recommend in any case use it for electron project – it is way to nowhere — some tool (e.g. electron-builder or electron-rebuild (if for some reasons you cannot use electron-builder ;))) should be used).

@rgbkrk
Copy link
Author

rgbkrk commented Nov 8, 2016

Awesome, thanks @develar!

@develar
Copy link

develar commented Nov 9, 2016

Due to #1749 yarn will be still not supported by electron-builder (probably I will send PR to fix it).

@develar
Copy link

develar commented Nov 9, 2016

Issue on electron-builder side — electron-userland/electron-builder#861

@busches
Copy link
Contributor

busches commented Dec 1, 2016

As @Blaccexican and @develar mentioned, the docs now mention that yarn install --force is the equivalent to npm rebuild. Can this be closed @rgbkrk?

@develar
Copy link

develar commented Dec 1, 2016

@busches Strictly speaking, it is not equivalent. yarn does it more slowly and touch more than need. Maybe I am wrong, but it is what I saw several weeks ago. electron-builder currently uses another approach in case of yarn to rebuild. But in general case — yes, I suggest to close issue since it is more electron issue then yarn (i.e. you should not in any case use it to rebuild native deps for electron).

@gaelollivier
Copy link

npm rebuild can possibly work offline if the build tasks don't download anything. yarn install --force can't. As @develar said, it's also much slower. So we still can't use yarn to rebuild deps in a Docker for example

@rgbkrk
Copy link
Author

rgbkrk commented Dec 1, 2016

Since my needs are addressed in Electron, the issue for me is closed. However, it still stands as @gaelduplessix points out that you can't rebuild using yarn (without doing the full thing).

@LaurensRietveld
Copy link

I agree with @gaelduplessix : rebuilding deps in a docker-build scenario is a use case that's probably quite common. Having the real npm rebuild command here would be great.

@davidgoli
Copy link

yarn install is deprecated by yarn add, and yarn add --force does not respect the versions specified in package.json or yarn.lock. yarn add --force is not equivalent to npm rebuild.

@arcanis
Copy link
Member

arcanis commented Apr 28, 2017

Note: yarn install is not deprecated by yarn add (however, yarn install <pkg-name> is deprecated by yarn add). Furthermore, the offline mirror feature makes it possible to run the install without needing any network capabilities.

@jedwards1211
Copy link

@aj0strow yeah no kidding :)

@williamboman
Copy link

$ yarn and have native extensions rebuild.

How would yarn know which Node runtime version a dependency tree has been installed & built with?

@aj0strow
Copy link

@williamboman put it at the top of yarn.lock.

# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v2    <-- bump version

$NODE=5.6.0    # or whatever version / syntax

# ... dependencies ...

@williamboman
Copy link

How would it know when a dependency requires a rebuild? I don't think a diff on the major version number of the Node runtime necessarily requires a rebuild. Also, would that require every developer installing dependencies to run the exact same Node version?

@aj0strow
Copy link

aj0strow commented Jun 28, 2017

@williamboman on a team of just me. You're right it doesn't belong in yarn.lock.

How often do you update node? I do maybe 2-3 times a year. Considering how infrequent, auto detecting likely has diminishing returns. yarn rebuild that rebuilds everything is probably the way to go.

If detecting is important, it would be ideal to introspect the binaries instead of writing a node version file (have to explain not to check it in to git). I'm not familiar with native extensions (gyp?) but yarn seems to know when they are absent, so maybe there's a way to detect if out of sync with node version.

@mgol
Copy link

mgol commented Jun 28, 2017

@williamboman

How would it know when a dependency requires a rebuild?

This is a solved problem; npm & node-gyp already know that, no need to reinvent the wheel. On the C side there's NODE_MODULE_VERSION and on the JS side there's process.versions.modules.

@aj0strow

How often do you update node? I do maybe 2-3 times a year. Considering how infrequent, auto detecting likely has diminishing returns.

I update Node wherever a new minor/patch release comes out. Sometimes twice in a week. Different people have different needs, rebuilds should happen only when NODE_MODULE_VERSION is bumped which is easily detectable.

@vkrol
Copy link
Contributor

vkrol commented Sep 21, 2017

We have some discussion with @BYK about it in Discord:

Expand me

vkrol

Hello. I found some annoying problem with the node-sass (and probably with other binary dependencies) and updating Node.js to new major version.
Steps:
1. Install Node.js 7.x
2. Add the node-sass dependency to the project via Yarn
3. Update Node.js to 8.x (new NODE_MODULE_VERSION)
4. Run "yarn install" (nothing happens)
5. Run "yarn run node-sass"
Error:

Error: Missing binding C:\...\node_modules\node-sass\vendor\win32-x64-57\binding.node
Node Sass could not find a binding for your current environment: Windows 64-bit with Node.js 8.x


Found bindings for the following environments:
  - Windows 64-bit with Node.js 7.x

This usually happens because your environment has changed since running `npm install`.
Run `npm rebuild node-sass --force` to build the binding for your current environment.

Is there any official solution of this problem?

byk

when you upgrade node versions, yarn doesn't know about native built artifacts. this was being discussed somewhere but I don't remember the outcome
for now you can delete ./node_modules/.yarn-integrity to force a reinstall
or just try yarn -f
so it would recompile those bindings

vkrol

i was thinking that this can help somehow https://media.discordapp.net/attachments/226793650552569856/360395418254835713/image.png?width=400&height=272

byk

I think arcanis added that field recently and it sure can help. That said we need to store the last node version those artifacts were built with to be able to retrigger a build
it is tricky but may be a nice addition
or may be just yarn install --rebuild-artifacts
we have a similar behavior for yarn global add which forces a rebuild of all artifacts
which is quite annoying 😄
this can fix those problems both

vkrol

That said we need to store the last node version those artifacts were built with to be able to retrigger a build
I think that this is the very good idea.
Ideally "yarn install" should reinstall binary dependencies without additional user actions.

byk

I agree
Would you mind creating an issue for that with some context from this convo so we don't forget?
I can't promise to work on it but I can promise to make the ticket handsome enough to lure potential contributors

romanschejbal added a commit to romanschejbal/yarn that referenced this issue Oct 20, 2017
@BYK BYK closed this as completed in #4750 Oct 26, 2017
BYK pushed a commit that referenced this issue Oct 26, 2017
**Summary**

Fixes #756. We have multiple versions of our app and each one uses a different version of node. 
Therefore we need to rebuild our `node-sass` module every time we move from one to another. 

This PR addresses that by saving the NODE version those artifacts were built with within the `.yarn-integrity` file and triggers forced scripts install (only if the node version is different ofc).

**Test plan**

```
1. Install Node.js 7.x
2. Add the node-sass dependency to the project via Yarn
3. Update Node.js to 8.x (new NODE_VERSION)
4. Run "yarn install" (you should see yarn downloading fresh scripts/binaries)
```
joaolucasl pushed a commit to joaolucasl/yarn that referenced this issue Oct 27, 2017
…kg#4750)

**Summary**

Fixes yarnpkg#756. We have multiple versions of our app and each one uses a different version of node. 
Therefore we need to rebuild our `node-sass` module every time we move from one to another. 

This PR addresses that by saving the NODE version those artifacts were built with within the `.yarn-integrity` file and triggers forced scripts install (only if the node version is different ofc).

**Test plan**

```
1. Install Node.js 7.x
2. Add the node-sass dependency to the project via Yarn
3. Update Node.js to 8.x (new NODE_VERSION)
4. Run "yarn install" (you should see yarn downloading fresh scripts/binaries)
```
@jwchang0206
Copy link

Would yarn --force --build-from-source work?

@andreyrd
Copy link

The problem with yarn --force is that you then have to rebuild all packages. My use case is that I just want to rebuild node-sass when I switch node versions. yarn install node-sass --force prompts me to use yarn add node-sass which modifies my package.json.

@ctcpip
Copy link

ctcpip commented Aug 13, 2018

@andreyrd see #5271

@rynop
Copy link

rynop commented Aug 22, 2018

Is the workaround here til #5271 is implemented, to run npm rebuild?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests