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

Build environment? Cannot build on ubuntu. #590

Closed
davidfiala opened this issue May 29, 2024 · 7 comments
Closed

Build environment? Cannot build on ubuntu. #590

davidfiala opened this issue May 29, 2024 · 7 comments

Comments

@davidfiala
Copy link
Contributor

davidfiala commented May 29, 2024

Hi,

I was hoping to take a look at #555 but I noticed that on a fresh Ubuntu 23.10 with node v20.13.1 installed freshly via nvm I was unable to get the project to build properly without lots of hacking. And even then, I cannot get tests working.

What is your current developmental workstation build setup? Does it work with a fresh version of node? (ie, does it work if you haven't done any global npm installs?)

Some immediate observations:

  • @types/node seems needed, but isn't present in the main package.json
  • packageManager is missing in package.json, but I do see a yarn.lock file

I'd be happy to help contribute here (including starting with a BUILDING.md), but would appreciate some pointers to at least see what a working baseline build environment looks like. Thank you!

@aikoven
Copy link
Contributor

aikoven commented May 30, 2024

Hey @davidfiala! Thank you for your interest.

Our build environment currently is just NodeJS 18+ with Yarn.
My development workstation is a Mac, but I mostly rely on CI for builds and tests. It uses Ubuntu and the setup is fairly simple: https://github.com/deeplay-io/nice-grpc/blob/master/.github/workflows/ci.yaml

For now it runs on NodeJS versions 18 and 20. I haven't tried to run it on fresher versions yet.

You may want to try to replicate the CI workflow locally.

I'd be happy to help contribute here

I'd be glad to accept your contributions!

@davidfiala
Copy link
Contributor Author

davidfiala commented Jun 1, 2024

Hi @aikoven

Embarassed to admit it, but I've put in several hours looking at the setup and thinking about potential build improvements. It has led to several rabbit holes. I'd love to discuss alignment on some of them with you to see if you'd be open to accepting some wider ranging changes before I proceed at all.

My biggest sticker is that it seems that the project does not compile in a vanilla environment, in my experience. That'd be fresh unadulterated node+npm installation without any global packages on the host system. I have not dived too deep in to why the CI build does work, but my benchmark here is that a recent fresh Ubuntu dev system will work, cross platform with Mac too.

My other goal would be to get tsconfig aligned across the project and get vscode to play ball with the tsconfig. Right now, I think some of the src/file expressions preclude some files from properly being recognized as in the project or not, leading to red squiggles and inability to perform intellisense.

Potential areas I'd love to align on, based on my rabbit holes so far:

  • upgrade over to yarn 4.x
  • clean up deps/devdeps so that they reflect the true dependencies (on a vanilla dev system)
  • switch to modern stephenh/ts-proto for generation and drop google-protobuf (not seeing much action these days)
  • unify to a single tsconfig.root.json in the project root, adopt overrides on a per-project basis
    • upgrade lib/target towards ES2018 or higher
  • switch to ESM internally everywhere (except for jest's snapshotSerializer which seems to require CJS per Support ESM versions of all pluggable modules jestjs/jest#11167)
    • this is a bit larger, as I've seen in my refactoring:
      • cleanup the tsconfigs so that src/test files are properly included
  • go ahead and cut over from lerna to nx?
  • and plenty of other tangential small things in the move to pure ESM (where possible) and ts-jest and more cleanly generated ts-proto
  • might need to be much larger commits than is generally healthy since some of this work is difficult to do in pieces, I think. At least for the time that I can agree to commit to help :( I'm sorry- and I know it's bad.
  • drop anything that still exists for pre Node 18.x reasons

As for switching to ESM everywhere, I think we can still output in any format if we had to. esbuild, etc could help if tsc gets annoying.

It's kind of a loose set of notes/ideas.. sorry. But I've had to timebox myself, realizing that if I proceed you may not accept the changes since they'll become pretty large. It's getting a little hairy. I'm also not convinced that for the time I can give to help that I can chunk this in to many fine-grained commits. I'm absolutely swamped over at Teclada, but I do want to help nice-grpc in a better place.. especially with bugs like #555 looking very scary. I'm separately working on grpc-js bug fixes and I don't want to particularly risk being incompatible with nice-grpc.

I'd be happy to jump on a chat anytime to discuss realtime, too. WDYT?

@aikoven
Copy link
Contributor

aikoven commented Jun 2, 2024

Hey @davidfiala!

I am not directly opposed to your modernization proposal, but are you sure all of this is required to fix build problems? What problem exactly you got with the build by the way?

Below I will leave comments on each of the proposals. But something tells me that we can unlock your work on #555 with much much less blood.

My other goal would be to get tsconfig aligned across the project and get vscode to play ball with the tsconfig. Right now, I think some of the src/file expressions preclude some files from properly being recognized as in the project or not, leading to red squiggles and inability to perform intellisense.

What files are we talking about? I am using VSCode to develop nice-grpc and everything works just fine for me.

upgrade over to yarn 4.x

That would be nice! I would also consider migrating to npm, to simplify things. Using yarn is just my old-school habit.

switch to modern stephenh/ts-proto for generation and drop google-protobuf (not seeing much action these days)

The only package that uses google-protobuf in its implementation currently is the server reflection library. That's because reflection protobufs are written in protobuf v2, which at that time was supported by ts-proto only for parsing but not serialization. It would be great to migrate if that's possible now.

Apart from that, we provide support for google-protobuf in nice-grpc and nice-grpc-web and I don't want to drop it, because it can aid the migration of old code to nice-grpc from grpc-js/grpc-web where google-protobuf is still often used.

upgrade lib/target towards ES2018 or higher

It's fine for NodeJS, but most of our packages can be used in the browser and other platforms. That's why we use @tsconfig/recommended, which currently has es2016 target. I worry that this change could break someone.

switch to ESM internally everywhere

I think we can still output in any format if we had to. esbuild, etc could help if tsc gets annoying.

I have some concerns about that.

First of all, I don't see a way we could drop CommonJS output for now. This would be more or less acceptable if our only consumer was application code. But our packages are broadly used in libraries, and this change would force them to switch to ESM as well.

Having dual output sounds better, but has a price of a more complicated build system. To be honest, I don't see benefits that would justify this change.


To sum up, I am definitely up for modernizing things, especially if that leads to simplification. On the other hand, complicating things does not sound right to me, even if that leads to a more modern setup.

That said, I sure hope that you acknowledge that all of the above is largely unrelated to #555.

I'd be happy to jump on a chat anytime to discuss realtime, too. WDYT?

Absolutely! I'm on Telegram @aikoven and Discord @aikoven

@davidfiala
Copy link
Contributor Author

Thanks for your reply. Definitely not trying to complicate anything. My aim is to get the basic repos building on stock Ubuntu and second to that ensure that the configs and dependencies for each package are setup so that vscode can also recognize everything as well.

Re: things like #555, I agree its likely unrelated. I'm just unable to compile and contribute to anything at the moment.

Just FYI, here's where I am starting and why I'm surprised that the CI is working.

fiala@u23:/tmp$ cat /etc/issue
Ubuntu 23.10 \n \l

fiala@u23:/tmp$ yarn --version
4.2.2
fiala@u23:/tmp$ node --version
v22.2.0

fiala@u23:/tmp$ git clone https://github.com/deeplay-io/nice-grpc.git
Cloning into 'nice-grpc'...
remote: Enumerating objects: 4096, done.
remote: Counting objects: 100% (1347/1347), done.
remote: Compressing objects: 100% (691/691), done.
remote: Total 4096 (delta 1076), reused 833 (delta 653), pack-reused 2749
Receiving objects: 100% (4096/4096), 2.35 MiB | 9.88 MiB/s, done.
Resolving deltas: 100% (3011/3011), done.


fiala@u23:/tmp$ cd nice-grpc/


fiala@u23:/tmp/nice-grpc$ yarn
! The local project doesn't define a 'packageManager' field. Corepack will now add one referencing yarn@4.2.2+sha256.1aa43a5304405be7a7cb9cb5de7b97de9c4e8ddd3273e4dad00d6ae3eb39f0ef.
! For more details about this field, consult the documentation at https://nodejs.org/api/packages.html#packagemanager

➤ YN0087: Migrated your project to the latest Yarn version 🚀

➤ YN0000: · Yarn 4.2.2
➤ YN0000: ┌ Project validation
➤ YN0057: │ nice-grpc-root: 'nohoist' is deprecated, please use 'installConfig.hoistingLimits' instead
➤ YN0000: └ Completed
➤ YN0000: ┌ Resolution step
➤ YN0085: │ + @grpc/grpc-js@npm:1.9.14, @improbable-eng/grpc-web@npm:0.15.0, @opentelemetry/api@npm:1.8.0, @opentelemetry/sdk-node@npm:0.49.1, @opentelemetry/semantic-conventions@npm:1.24.1, @tsconfig/node14@npm:14.1.2, and 1445 more.
➤ YN0000: └ Completed in 0s 997ms
➤ YN0000: ┌ Post-resolution validation
➤ YN0002: │ nice-grpc-root@workspace:. doesn't provide @types/node (p25d5f), requested by ts-node.
➤ YN0002: │ nice-grpc-web@workspace:packages/nice-grpc-web doesn't provide @types/node (p80a03), requested by ts-node.
➤ YN0002: │ nice-grpc-web@workspace:packages/nice-grpc-web doesn't provide typescript (p6a5b5), requested by ts-node.
➤ YN0086: │ Some peer dependencies are incorrectly met; run yarn explain peer-requirements <hash> for details, where <hash> is the six-letter p-prefixed code.
➤ YN0000: └ Completed
➤ YN0000: ┌ Fetch step
➤ YN0000: └ Completed in 0s 885ms
➤ YN0000: ┌ Link step
➤ YN0007: │ nx@npm:19.1.1 [231b4] must be built because it never has been before or the last one failed
➤ YN0007: │ grpc-tools@npm:1.12.4 must be built because it never has been before or the last one failed
➤ YN0007: │ protobufjs@npm:7.3.0 must be built because it never has been before or the last one failed
➤ YN0007: │ edgedriver@npm:5.3.5 must be built because it never has been before or the last one failed
➤ YN0007: │ chromedriver@npm:125.0.3 must be built because it never has been before or the last one failed
➤ YN0007: │ esbuild@npm:0.18.20 must be built because it never has been before or the last one failed
➤ YN0007: │ geckodriver@npm:4.3.2 must be built because it never has been before or the last one failed
➤ YN0007: │ esbuild@npm:0.14.54 must be built because it never has been before or the last one failed
➤ YN0007: │ edgedriver@npm:5.5.0 must be built because it never has been before or the last one failed
➤ YN0007: │ @swc/core@npm:1.4.4 [08971] must be built because it never has been before or the last one failed
➤ YN0007: │ cpu-features@npm:0.0.4 must be built because it never has been before or the last one failed
➤ YN0009: │ cpu-features@npm:0.0.4 couldn't be built successfully (exit code 1, logs can be found here: /tmp/xfs-691ead6b/build.log)
➤ YN0007: │ ssh2@npm:1.11.0 must be built because it never has been before or the last one failed
➤ YN0000: └ Completed in 9s 33ms
➤ YN0000: · Done with warnings in 11s 53ms


fiala@u23:/tmp/nice-grpc$ yarn prepare
(node:1018771) [DEP0040] DeprecationWarning: The `punycode` module is deprecated. Please use a userland alternative instead.
(Use `node --trace-deprecation ...` to show where the warning was created)
lerna notice cli v8.1.3
lerna info versioning independent

 Lerna (powered by Nx)   Running target prepare for 11 projects

   ✖  nice-grpc:prepare
      > nice-grpc@2.1.8 prepare:proto
      > npm run prepare:proto:grpc-js && npm run prepare:proto:ts-proto


      > nice-grpc@2.1.8 prepare:proto:grpc-js
      > mkdirp ./fixtures/grpc-js && grpc_tools_node_protoc --plugin=protoc-gen-grpc=./node_modules/.bin/grpc_tools_node_protoc_plugin --plugin=protoc-gen-ts=./node_modules/.bin/protoc-gen-ts --js_out=import_style=commonjs,binary:./fixtures/grpc-js --ts_out=grpc_js:./fixtures/grpc-js --grpc_out=grpc_js:./fixtures/grpc-js -I fixtures fixtures/*.proto

      ./node_modules/.bin/protoc-gen-ts: program not found or is not executable
      Please specify a program using absolute path or make sure the program is available in your PATH system variable
      --ts_out: protoc-gen-ts: Plugin failed with status code 1.
      /tmp/nice-grpc/node_modules/grpc-tools/bin/protoc.js:41
          throw error;
          ^

      Error: Command failed: /tmp/nice-grpc/node_modules/grpc-tools/bin/protoc --plugin=protoc-gen-grpc=/tmp/nice-grpc/node_modules/grpc-tools/bin/grpc_node_plugin --plugin=protoc-gen-grpc=./node_modules/.bin/grpc_tools_node_protoc_plugin --plugin=protoc-gen-ts=./node_modules/.bin/protoc-gen-ts --js_out=import_style=commonjs,binary:./fixtures/grpc-js --ts_out=grpc_js:./fixtures/grpc-js --grpc_out=grpc_js:./fixtures/grpc-js -I fixtures fixtures/test.proto
      ./node_modules/.bin/protoc-gen-ts: program not found or is not executable
      Please specify a program using absolute path or make sure the program is available in your PATH system variable
      --ts_out: protoc-gen-ts: Plugin failed with status code 1.

          at genericNodeError (node:internal/errors:983:15)
          at wrappedFn (node:internal/errors:537:14)
          at ChildProcess.exithandler (node:child_process:421:12)
          at ChildProcess.emit (node:events:520:28)
          at maybeClose (node:internal/child_process:1105:16)
          at Socket.<anonymous> (node:internal/child_process:457:11)
          at Socket.emit (node:events:520:28)
          at Pipe.<anonymous> (node:net:338:12) {
        code: 1,
        killed: false,
        signal: null,
        cmd: '/tmp/nice-grpc/node_modules/grpc-tools/bin/protoc --plugin=protoc-gen-grpc=/tmp/nice-grpc/node_modules/grpc-tools/bin/grpc_node_plugin --plugin=protoc-gen-grpc=./node_modules/.bin/grpc_tools_node_protoc_plugin --plugin=protoc-gen-ts=./node_modules/.bin/protoc-gen-ts --js_out=import_style=commonjs,binary:./fixtures/grpc-js --ts_out=grpc_js:./fixtures/grpc-js --grpc_out=grpc_js:./fixtures/grpc-js -I fixtures fixtures/test.proto'
      }

      Node.js v22.2.0
      npm error Lifecycle script `prepare:proto:grpc-js` failed with error:
      npm error Error: command failed
      npm error   in workspace: nice-grpc@2.1.8
      npm error   at location: /tmp/nice-grpc/packages/nice-grpc
      npm error Lifecycle script `prepare:proto` failed with error:
      npm error Error: command failed
      npm error   in workspace: nice-grpc@2.1.8
      npm error   at location: /tmp/nice-grpc/packages/nice-grpc



—————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
   ✖  nice-grpc-web:prepare
      > nice-grpc-web@3.3.3 prepare:grpcwebproxy
      > path-exists grpcwebproxy || node scripts/download-grpcwebproxy.js

      (node:1018929) [DEP0040] DeprecationWarning: The `punycode` module is deprecated. Please use a userland alternative instead.
      (Use `node --trace-deprecation ...` to show where the warning was created)
      Downloading grpcwebproxy

      > nice-grpc-web@3.3.3 prepare:proto
      > npm run prepare:proto:grpc-web && npm run prepare:proto:ts-proto


      > nice-grpc-web@3.3.3 prepare:proto:grpc-web
      > mkdirp ./fixtures/grpc-web && grpc_tools_node_protoc --plugin=protoc-gen-ts=./node_modules/.bin/protoc-gen-ts --js_out=import_style=commonjs,binary:./fixtures/grpc-web --ts_out=service=grpc-web:./fixtures/grpc-web -I fixtures fixtures/*.prot

      ./node_modules/.bin/protoc-gen-ts: program not found or is not executable
      Please specify a program using absolute path or make sure the program is available in your PATH system variable
      --ts_out: protoc-gen-ts: Plugin failed with status code 1.
      /tmp/nice-grpc/node_modules/grpc-tools/bin/protoc.js:41
          throw error;
          ^

      Error: Command failed: /tmp/nice-grpc/node_modules/grpc-tools/bin/protoc --plugin=protoc-gen-grpc=/tmp/nice-grpc/node_modules/grpc-tools/bin/grpc_node_plugin --plugin=protoc-gen-ts=./node_modules/.bin/protoc-gen-ts --js_out=import_style=commonjs,binary:./fixtures/grpc-web --ts_out=service=grpc-web:./fixtures/grpc-web -I fixtures fixtures/test.proto
      ./node_modules/.bin/protoc-gen-ts: program not found or is not executable
      Please specify a program using absolute path or make sure the program is available in your PATH system variable
      --ts_out: protoc-gen-ts: Plugin failed with status code 1.

          at genericNodeError (node:internal/errors:983:15)
          at wrappedFn (node:internal/errors:537:14)
          at ChildProcess.exithandler (node:child_process:421:12)
          at ChildProcess.emit (node:events:520:28)
          at maybeClose (node:internal/child_process:1105:16)
          at Socket.<anonymous> (node:internal/child_process:457:11)
          at Socket.emit (node:events:520:28)
          at Pipe.<anonymous> (node:net:338:12) {
        code: 1,
        killed: false,
        signal: null,
        cmd: '/tmp/nice-grpc/node_modules/grpc-tools/bin/protoc --plugin=protoc-gen-grpc=/tmp/nice-grpc/node_modules/grpc-tools/bin/grpc_node_plugin --plugin=protoc-gen-ts=./node_modules/.bin/protoc-gen-ts --js_out=import_style=commonjs,binary:./fixtures/grpc-web --ts_out=service=grpc-web:./fixtures/grpc-web -I fixtures fixtures/test.proto'
      }

      Node.js v22.2.0
      npm error Lifecycle script `prepare:proto:grpc-web` failed with error:
      npm error Error: command failed
      npm error   in workspace: nice-grpc-web@3.3.3
      npm error   at location: /tmp/nice-grpc/packages/nice-grpc-web
      npm error Lifecycle script `prepare:proto` failed with error:
      npm error Error: command failed
      npm error   in workspace: nice-grpc-web@3.3.3
      npm error   at location: /tmp/nice-grpc/packages/nice-grpc-web



—————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————

 Lerna (powered by Nx)   Ran target prepare for 11 projects (2s)

   ✔  0/2 succeeded [0 read from cache]

   ✖  2/2 targets failed, including the following:

      - nice-grpc:prepare
      - nice-grpc-web:prepare

 Hint: Try "nx view-logs" to get structured, searchable errors logs in your browser.

I tried with node v20.14.0 and v18.20.3 just to be safe. corepack always pushes me to 4.2.2 by default citing ! The local project doesn't define a 'packageManager' field. Corepack will now add one referencing yarn@4.2.2+sha256.1aa43a5304405be7a7cb9cb5de7b97de9c4e8ddd3273e4dad00d6ae3eb39f0ef.

Trying to resolve this led me down the rabbit hole of seeing many things to potentially improve along the way. Hence my original issue about making a BUILDING.md that works on common dev environments :)

If you don't mind, could you post your mac's default yarn and node versions? Could you post if you have anything globally installed in your node installation?

Thank you!

@aikoven
Copy link
Contributor

aikoven commented Jun 4, 2024

Thanks for the reproduction steps!

I see now that the problem is caused by yarn 4 producing a little different node_modules layout (particularly the location of binaries).

Here are the versions installed on my Mac:

❯ node --version
v18.20.2

❯ yarn --version
1.22.22

I checked the CI logs and it appears that GitHub setup-node action also uses yarn 1.22.22 on both NodeJS 18 and NodeJS 20.

I'm not sure whether it is possible to lock yarn to v1 via packageManager field. Can you please try the setup with "packageManager": "yarn@1.22.22"?

I also tried installing dependencies using npm, which resulted in same errors with missing binaries. If the packageManager setting won't help, we could try to update the binary paths to match the structure produced by npm.

@davidfiala
Copy link
Contributor Author

Got it! Yes, this works!

package.json added: "packageManager": "yarn@1.22.22"

$ yarn
! Corepack is about to download https://registry.yarnpkg.com/yarn/-/yarn-1.22.22.tgz
? Do you want to continue? [Y/n] y

yarn install v1.22.22
[1/4] Resolving packages...
.......

In my other projects using yarn 4.x, I often don't need to pass the path to the tools for things like proto compilers and plugins. Yarn seems to put it on the path for me. I think that's something we'll be able to take advantage of here if we upgrade yarn.

Thank you for the help!

davidfiala added a commit to davidfiala/nice-grpc that referenced this issue Jun 4, 2024
Per discussion in deeplay-io#590 this version of yarn is known working
@davidfiala
Copy link
Contributor Author

As we've merged the yarn version info in to master, I'll close this issue. In the future we can reference the discussion here as needed for updating any build environment or steps.

Using Ubuntu 23.10 with nvm to manage node versions, I can build nice-grpc using node v18.x and v20.x and v22.x at this time.

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

No branches or pull requests

2 participants