Grpc-web: ES Modules Support?

Created on 12 Apr 2019  路  7Comments  路  Source: grpc/grpc-web

Hi, I'm new to grpc-web and I was checking your Web basics tutorial when I noticed that the client code generator only supports Closure and common.js

Now that ES Modules are supported on all modern browsers, is there a chance that you'll have a generator for them? That would allow the library to be used without any build process which would be great imho

Most helpful comment

This actually seems to be a real problem when trying to use grpc-web with something like create-react-app or any Babel 7 Typescript. Since they don't support commonjs only ESModules. Currently the only solution seems to be to manually rollup the exports using something like this https://github.com/rollup/rollup-plugin-commonjs. Would love to find a more permanent solution though.

All 7 comments

This isn't a direct answer, but the TypeScript output _does_ support modules. If you're not using TS in your project, a workaround would be to re-compile from the TS output of protoc down to ES6.

@jonahbron
I tried this, it was a bit annoying to configure but I managed to get it working

Here's a sample bash script for generating the ts files and the tsconfig.json to compile it to esm in case anyone has this same problem

protoc -I ./protos protos/*.proto --js_out=import_style=commonjs:./protos/ts --grpc-web_out=import_style=typescript,mode=grpcwebtext:./protos/ts
{
  "compilerOptions": {
    "target": "es2015", 
    "module": "es2015",
    "allowJs": true,
    "outDir": "../esm",
    "rootDir": "./",
    "strict": false,
    "moduleResolution": "node",
    "esModuleInterop": true
  }
}

Then again this only worked for the grpc-web_out files, the other files were still generated as commonjs modules, but I guess it's something

This actually seems to be a real problem when trying to use grpc-web with something like create-react-app or any Babel 7 Typescript. Since they don't support commonjs only ESModules. Currently the only solution seems to be to manually rollup the exports using something like this https://github.com/rollup/rollup-plugin-commonjs. Would love to find a more permanent solution though.

ESM modules would be really nice.

In the mean time, if you use grpc web with stencil and rollup, see this comment https://github.com/ionic-team/stencil/issues/1343#issuecomment-589528554

That would allow the library to be used without any build process which would be great imho

By the way, this is only true if both grpc-web AND the generated client-stubs has esm-support, so this issue has to be solved in two parts:

Part 1: Generating an esm-compatible grpc-web-client:

image

  • Part 1 is 99% solved already with the import_style=typescript-option :+1:
  • The only thing that is left for me to do after generating the EchoServiceClient.ts above, is to update the import paths to be esm-compatible.

_Example:_
| Generated import paths | Modified to be esm-compatible | CDN alternative |
|------------------|-----------------------------------------|----------------|
| image | image | image |

  • FYI: Here is my protoc-gen-grpc-web-version:
$ brew info protoc-gen-grpc-web
protoc-gen-grpc-web: stable 1.2.1 (bottled)

Part 2: Convert the grpc-web-package to be esm-compatible.

  • After modifying the paths in Part 1, I will still get an error if I try to run my generated client directly in a browser, because the modules imported from ../node-modules/grpc-web/index.js and https://cdn.jsdelivr.net/npm/[email protected]/index.min.js are NOT esm-compatible.

  • Neither is './echo_pb.js', and it's depedency ../node-modules/google-protobuf/google-protobuf.js, for that matter, but that is out of scope of this repo.

  • This inspired me to explore how the grpc-web-package can be converted to be esm-compatible in a PR here --> https://github.com/Arxcis/grpc-web/pull/1
  • I would love to discuss this more :rocket:

Part 2: Work in progress update

  • So I have been hacking along on my fork PR of grpc-web here --> https://github.com/Arxcis/grpc-web/pull/2
  • I have put together a "transpiler" of sorts, which takes the exports.js-file as an input, and traverses all the dependencies, and outputs a es_modules-folder, with transpiled .js files.
  • I have gotten to a point where the browser is able to load all the modules - but not run. (see demo here --> https://github.com/Arxcis/grpc-web/pull/2)
  • The main issue I am running into now, is that the ~closure-library~ the code I have generated has a few circular dependencies of top-level values, which the browser's ES modules loader is not too happy about. (details here --> https://github.com/Arxcis/grpc-web/pull/2)
  • ~I honestly don't know how to proceed from here~ I think I would have to improve my generator to not generate top-level values, bu try to transform modules into ES classes instead, to solve the circular dependency issues :pray:
  • Alternatively We could generate modules wrapped in an immediately invoked function closure, which returns the module.
  • Alterntive 2: We could just write code without circular deps. I am not holding my breath 馃槄
Was this page helpful?
0 / 5 - 0 ratings

Related issues

joaomlneto picture joaomlneto  路  4Comments

verihelp-vaibhav picture verihelp-vaibhav  路  5Comments

JuliusKoronci picture JuliusKoronci  路  4Comments

barrymichaeldoyle picture barrymichaeldoyle  路  4Comments

smnbbrv picture smnbbrv  路  4Comments