Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 57 additions & 0 deletions examples/js-es-custom-outputpath/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# JavaScript ES Modules with Custom Output Path

This example demonstrates using a custom `outputPath` specifically for the ES modules plugin.

## Overview

This example shows how to configure JavaScript/TypeScript code generation with a plugin-specific output path, which is useful in monorepo scenarios where different code generation plugins need to output to different locations.

## Configuration

```nix
languages.js = {
enable = true;
es = {
enable = true;
outputPath = "proto/gen/js"; # Custom path for ES modules
options = [
"target=ts"
"import_extension=.js"
"json_types=true"
];
};
};
```

## Key Features

- **Plugin-specific output paths**: Set different output directories for different plugins
- **TypeScript target**: Generates `.ts` files with type definitions
- **ES modules**: Modern JavaScript with import/export syntax
- **JSON types**: Includes JSON type definitions for serialization

## Usage

```bash
# Generate TypeScript code
nix run

# View generated files
ls proto/gen/js/example/v1/
```

## Generated Files

- `proto/gen/js/example/v1/example_pb.ts` - Generated TypeScript protobuf messages

## Use Cases

This pattern is especially useful when:
- Working with monorepos where frontend and backend have different structure requirements
- Using multiple JS plugins (ES, gRPC-Web, Twirp) that need separate output locations
- Integrating with existing project structures that have specific directory conventions

## See Also

- [js-example](../js-example/) - Basic JavaScript example with default paths
- [js-grpc-web](../js-grpc-web/) - gRPC-Web example
113 changes: 113 additions & 0 deletions examples/js-es-custom-outputpath/flake.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

56 changes: 56 additions & 0 deletions examples/js-es-custom-outputpath/flake.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
{
description = "JavaScript ES modules example with custom outputPath - tests plugin-specific output paths";

inputs = {
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
flake-utils.url = "github:numtide/flake-utils";
# bufrnix.url = "github:conneroisu/bufrnix";
bufrnix.url = "path:../..";
bufrnix.inputs.nixpkgs.follows = "nixpkgs";
};

outputs = {
nixpkgs,
flake-utils,
bufrnix,
...
}:
flake-utils.lib.eachDefaultSystem (system: let
pkgs = nixpkgs.legacyPackages.${system};
in {
devShells.default = pkgs.mkShell {
packages = [
pkgs.nodejs
pkgs.nodePackages.typescript
];
};
packages = {
default = bufrnix.lib.mkBufrnixPackage {
inherit pkgs;

config = {
root = ./.;
protoc = {
sourceDirectories = ["./proto"];
includeDirectories = ["./proto"];
files = ["./proto/example/v1/example.proto"];
};
languages.js = {
enable = true;
# This demonstrates the bug: setting outputPath at ES plugin level
# Currently this gets ignored and uses the default "gen/js" instead
es = {
enable = true;
outputPath = "proto/gen/js"; # Custom path for ES modules
options = [
"target=ts"
"import_extension=.js"
"json_types=true"
];
};
};
};
};
};
});
}
23 changes: 23 additions & 0 deletions examples/js-es-custom-outputpath/proto/example/v1/example.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
syntax = "proto3";

package example.v1;

// Simple message for testing custom outputPath
message User {
string id = 1;
string name = 2;
string email = 3;
}

// Simple service for testing
service UserService {
rpc GetUser(GetUserRequest) returns (GetUserResponse);
}

message GetUserRequest {
string user_id = 1;
}

message GetUserResponse {
User user = 1;
}
27 changes: 18 additions & 9 deletions src/languages/js/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,13 @@ with lib; let
jsOptions = cfg.options;

# Import JS-specific sub-modules
# Use plugin-specific outputPath if set, otherwise fall back to parent outputPath
grpcWebModule = import ./grpc-web.nix {
inherit pkgs lib;
cfg =
cfg.grpcWeb
// {
outputPath = outputPath;
outputPath = if (cfg.grpcWeb.outputPath or null) != null then cfg.grpcWeb.outputPath else outputPath;
};
};

Expand All @@ -25,7 +26,7 @@ with lib; let
cfg =
cfg.twirp
// {
outputPath = outputPath;
outputPath = if (cfg.twirp.outputPath or null) != null then cfg.twirp.outputPath else outputPath;
};
};

Expand All @@ -47,7 +48,7 @@ with lib; let
cfg =
cfg.tsProto
// {
outputPath = outputPath;
outputPath = if (cfg.tsProto.outputPath or null) != null then cfg.tsProto.outputPath else outputPath;
};
};

Expand Down Expand Up @@ -78,27 +79,33 @@ in {
(optional (cfg.package != null)
"--js_out=import_style=commonjs,binary:${outputPath}")
++ (optionals cfg.es.enable (let
esOutputPath = if (cfg.es.outputPath != null) then cfg.es.outputPath else outputPath;
esOptions =
cfg.es.options
++ (optional (cfg.es.target != "") "target=${cfg.es.target}")
++ (optional (cfg.es.importExtension != "") "import_extension=${cfg.es.importExtension}");
in [
"--plugin=protoc-gen-es=${cfg.es.package}/bin/protoc-gen-es"
"--es_out=${outputPath}"
"--es_out=${esOutputPath}"
(optionalString (esOptions != []) "--es_opt=${concatStringsSep "," esOptions}")
]))
++ (optionals cfg.tsProto.enable (tsProtoModule.protocPlugins or []))
++ (combineModuleAttrs "protocPlugins");

# Initialization hook for JS
initHooks =
''
(let
esOutputPath = if (cfg.es.outputPath != null) then cfg.es.outputPath else outputPath;
in ''
# Create js-specific directories
mkdir -p "${outputPath}"
${optionalString cfg.es.enable ''
mkdir -p "${esOutputPath}"
''}
${optionalString (cfg.packageName != "") ''
echo "Creating JS package: ${cfg.packageName}"
''}
''
'')
+ concatStrings (catAttrs "initHooks" [
grpcWebModule
twirpModule
Expand All @@ -117,8 +124,10 @@ in {
''}

# Generate package.json for ES modules if requested
${optionalString (cfg.es.enable && cfg.es.generatePackageJson) ''
cat > ${outputPath}/package.json <<EOF
${optionalString (cfg.es.enable && cfg.es.generatePackageJson) (let
esOutputPath = if (cfg.es.outputPath != null) then cfg.es.outputPath else outputPath;
in ''
cat > ${esOutputPath}/package.json <<EOF
{
"name": "${
if cfg.es.packageName != ""
Expand Down Expand Up @@ -148,7 +157,7 @@ in {
}
EOF
echo "Generated package.json for ES modules"
''}
'')}
''
+ concatStrings (catAttrs "generateHooks" [
grpcWebModule
Expand Down
Loading