bufbuild / protobuf-es

Protocol Buffers for ECMAScript. The only JavaScript Protobuf library that is fully-compliant with Protobuf conformance tests.
Apache License 2.0
1.16k stars 69 forks source link

Allow custom import prefix #992

Closed DrBlury closed 4 weeks ago

DrBlury commented 1 month ago

With Deno 2 comes support for NPM packages. I would like to use the generated code in my Deno 2 Project but it creates the imports without the npm: prefix. Editing this in manually works no issues.

Providing an optional import prefix would resolve this issue. I understand that this is not a bug but I think this would benefit everyone using Deno 2 in the future.

lenaramisch commented 1 month ago

Great idea! We are facing the same problem while switching our services from nodejs to deno2. An optional import prefix would definitely help! 👍

TheSortex commented 1 month ago

I support this idea. Helps us too!

timostamm commented 1 month ago

This is about the npm-specifier for import statements, as in:

import express from "npm:express@4.18.2";

And the goal would be to change generated imports for the runtime library:

import { enumDesc, fileDesc, messageDesc } from "@bufbuild/protobuf/codegenv1";
import type { UInt32Value } from "@bufbuild/protobuf/wkt";

To... what exactly?

Should it be npm:@bufbuild/protobuf/codegenv1, or npm:@bufbuild/protobuf/codegenv1@2.2.0 or npm:@bufbuild/protobuf@2.2.0/codegenv1?

DrBlury commented 1 month ago

@timostamm Adding a prefix via options for the protoc-gen-es plugin would do the trick and would be flexible for the future. Default empty string.

So option 1 would be perfect! :)

version: v2
inputs:
  - directory: proto
plugins:
  - local: protoc-gen-es
    opt: 
      - target=ts
      - json_types=false
      - import_prefix='npm:'
    out: src/domain/model

should be enough. The imports which work are the following:

import type { GenFile, GenMessage } from "npm:@bufbuild/protobuf/codegenv1";
import { fileDesc, messageDesc } from "npm:@bufbuild/protobuf/codegenv1";
import type { Message } from "npm:@bufbuild/protobuf";
timostamm commented 4 weeks ago

We have a plugin option to "rewrite" imports - you can find more details here: https://github.com/bufbuild/protobuf-es/issues/947#issuecomment-2257889255

It can be specified multiple times, and accepts a value with the form<pattern>:<target>. Import paths that match pattern are replaced with target.

The example buf.gen.yaml config below updates the imports as suggested:

version: v2
plugins:
  - local: protoc-gen-es
    opt:
      - target=ts
      - rewrite_imports=@bufbuild/protobuf:npm:@bufbuild/protobuf
      - rewrite_imports=@bufbuild/protobuf/codegenv1:npm:@bufbuild/protobuf/codegenv1
    out: src/gen

Should yield:

import type { GenFile, GenMessage } from "npm:@bufbuild/protobuf/codegenv1";
import { fileDesc, messageDesc } from "npm:@bufbuild/protobuf/codegenv1";
import type { Message } from "npm:@bufbuild/protobuf";

But it doesn't 😝 We're expecting only one colon in the option - we're relaxing this in https://github.com/bufbuild/protobuf-es/pull/998.

timostamm commented 4 weeks ago

Released in v2.2.1.