grpc / grpc-web

gRPC for Web Clients
https://grpc.io
Apache License 2.0
8.54k stars 763 forks source link

Unable to import generated files with typescript #462

Open martijnjanssen opened 5 years ago

martijnjanssen commented 5 years ago

Importing generated files results in an error when running rollup: Error: 'GreetRequest' is not exported by proto/test_pb.js

While there are 3 generated files in the proto folder:

TestServiceClientPb.ts
test_pb.d.ts
test_pb.js

And importing them with:

import * as grpcWeb from 'grpc-web';
import { TestClient } from '../../proto/TestServiceClientPb';
import { GreetRequest } from '../../proto/test_pb';

The tsconfig.json is:

{
  "compilerOptions": {
    "target": "es6",
    "experimentalDecorators": true
  }
}

I have tried tons of stuff but can't seem to figure out the issue here. I'd greatly appreciate any pointers why this is going wrong.

clehene commented 5 years ago

I'm having the same problem. I ended up importing from js files and was wondering what's the difference? (note I have no TS / JS background :) )

skamoen commented 5 years ago

A solution is to use the rollup-plugin-commonjs. It's required to define namedExports manually, as indicated by the error rollop throws (https://rollupjs.org/guide/en#error-name-is-not-exported-by-module)

        commonjs({
            namedExports: {
              'proto/test_pb.js': [ 'Greeting', 'GreetRequest' ],
              'proto/test_grpc_web_pb.js':['TestClient']
            }
          }),

Feels a bit odd that this is required and I'm not sure whether this is a fix for something wrong somewhere else in the process...

clehene commented 5 years ago

I'm having the same problem. I ended up importing from js files and was wondering what's the difference? (note I have no TS / JS background :) )

What I mean is using import_style=commonjs+dts,mode=grpcweb seems to be working, but not sure what's the end result difference between this and using the import_style=typescript

scriptin commented 5 years ago

@clehene commonjs+dts creates *.js (sources) and *.d.ts (TS type definitions, w/o the code) files separately, while typescript is supposed to produce only *.ts files.

clehene commented 5 years ago

@scriptin thank you! I became aware of the type definitions soon after :))

midzdotdev commented 3 years ago

This issue seems to be critical to anybody using TypeScript with gRPC-Web, which I imagine would be a considerable proportion of users. As I understand it, TypeScript definition files (.d.ts) should not include any logic, purely types. Upon compilation into JavaScript, TS doesn't include any code from the .d.ts files.

When I run protoc with either import_style=typescript or import_style=commonjs+dts, the classes representing the message objects are present within a .d.ts file. I need to use these to use the service clients. If you try to import { HelloRequest } from './greet_pb' (a .d.ts file), you're greeted with a Module not found: Can't resolve './greet_pb'.

The services which are generated do rely on this TypeScript definitions file, but only in type space, and do not use them as values. We need to be able to use these as values, new GreeterClient(...) for example. I don't understand how anybody is able to use these without having errors?

I don't believe these message class objects should remain part of .d.ts files

johnlabarge commented 10 months ago

@midzdotdev did you come up with a workaround? I have this exact issue and it's torture.

sampajano commented 10 months ago

Without understanding too much details of the issues above, we have one Typescript example documented below as a typical way of how it could work :)

https://github.com/grpc/grpc-web/blob/master/net/grpc/gateway/examples/echo/ts-example/README.md

Note that that you need to modify the file's import style when using import_style=typescript.

martinslovacek commented 8 months ago

I am facing identical problem in a React+TypeScript+Vite application.

Used this call of protoc: protoc --proto_path={proto_path} --grpc-web_out=import_style=typescript,mode=grpcweb:src/gen --js_out=import_style=commonjs,binary:src/gen {my-entity.file}

I am able to import the MyEntityServiceClient from the generated MyEntityServiceClientPb.ts file. However, the request/response objects are defined in the 'myEntity_pb.js` file and they are not exported.

To get the app built, I modified the import to import * as myEntity_pb from './gen/myEntity_pb' and used the Request object with the myEntity. prefix. But this lead to a dead end on browser side:

Uncaught ReferenceError: require is not defined

sampajano commented 8 months ago

I'm not personally familiar with React / Vite, but recently someone made a demo of Vite + grpc-web, which you could check it out, and see if it helps :)

https://github.com/a2not/vite-grpc-web

martinslovacek commented 8 months ago

Thank you, I will check it out. BTW, using another Proto-TS generator (https://github.com/timostamm/protobuf-ts), I had success.

sampajano commented 8 months ago

Thank you, I will check it out. BTW, using another Proto-TS generator (https://github.com/timostamm/protobuf-ts), I had success.

good to note! thanks for the info!