ES Modules Support?
alangdm opened this issue Β· 26 comments
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
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 stenciljs/core#1343 (comment)
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:
- Part 1 is 99% solved already with the
import_style=typescript
-option π - The only thing that is left for me to do after generating the
EchoServiceClient.ts
above, is to update the import paths to beesm
-compatible.
Example:
Generated import paths | Modified to be esm -compatible |
CDN alternative |
---|---|---|
![]() |
![]() |
![]() |
- 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/grpc-web@1.2.1/index.min.js are NOTesm
-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 beesm
-compatible in a PR here --> Arxcis#1 -
I would love to discuss this more π
Part 2: Work in progress update
- So I have been hacking along on my fork PR of
grpc-web
here --> Arxcis#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 --> Arxcis#2)
- The main issue I am running into now, is that the
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 --> Arxcis#2)closure-library
I honestly don't know how to proceed from hereI 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 π- 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 π
Any progress on this issue?
Any progress on this issue?
FYI: My experiment mentioned above, ended without any success. I have no affiliation with the maintainers of this repo. I don't know what the plan is. I am patiently waiting like you π
I am also waiting patiently. π’
Are there any plans for this to be worked on? Currently having issues with using Vite alongside grpc-web.
Are there any plans for this to be worked on? Currently having issues with using Vite alongside grpc-web.
You can use this package https://github.com/timostamm/protobuf-ts which works great with Vite
Please π
is grpc supported es6?
Definitely would be nice to have for bundlers that don't support CommonJS. I'll try that rollup solution above, but first-party support would be much preferred.
Not sure if this will work for everyone, but it worked for me. I had this error when trying to import the generated client in an ESM project:
require is not defined in ES module scope, you can use import instead
This file is being treated as an ES module because it has a '.js' file extension and 'X\package.json' contains "type": "module".
To treat it as a CommonJS script, rename it to use the '.cjs' file extension
I fixed it by creating a package.json
in the directory of my generated client (e.g. @/generated
) with the following contents:
{
"type": "commonjs",
"main": "xyz_client_pb.js",
"types": "xyz_client_pb.d.ts",
"dependencies": {
"google-protobuf": "^3.21.2"
}
}
I needed to install google-protobuf
from within the directory for this to work.
This essentially un-sets your "type": "module"
setting for only those generated files. It seems you can pretty much use it as normal, for example:
import { XYZRequest } from "@/generated"
import { XYZClient } from "@/generated/xyz_client_grpc_pb"
We got this working by using moduleResolution: "bundler"
and tsc-alias
to rewrite imports missing .js
extension.
I switched to @connectrpc/connect-web a couple of months ago because I ran into an issue with the client code that I couldn't hack my way out of anymore. The refactor was a headache, but the whole experience is definitely cleaner now. This issue really needs to take center stage if the gRPC-Web team doesn't want to lose more developers. The lack of modernity in the client code is baffling.
We also switched to connect-web for the very same reasons @PrestonMonteWest explained.
we need esm!
@sampajano It seems you are the active maintainer of this project, could you please take a look at this feature requestπ₯Ί
Hihi.. thanks for pinging on this FR.. Sorry for the inconveniences!
Lately we're working on migrating our codebase to Typescript, at which time i will need to rework all the toolchains we have. And i will ensure to take a look at improving our usability here as well!
@loeffel-io @ttc0419 FYI!
@sampajano @loeffel-io @ttc0419 hi, any update?
Hello, any update? π
Hi.. Apologize for the delays!
I was able to finish most of the Typescript migrations internally, but not yet able to start exporting those changes into Github.
This year we're getting some new help on this project, so i'm hopefully we'd start making some good progress!
Apologize for all the waiting but ES module support is important and high on the list! I will post update when we have one.
Thanks!!