Javascript - where is google-protobuf.js

605 views
Skip to first unread message

Michael Lum

unread,
Jul 9, 2020, 2:45:41 PM7/9/20
to Protocol Buffers
Hi, I've searched for quite a while but I cannot find the file: google-protobuf.js.


I'm using the CommonJS imports instructions.

I built my protobuf files using a docker image that contains the Javascript plugin this way:

docker run --rm --user "$(id -u):$(id -g)" -v $(pwd):$(pwd) -w $(pwd) gwihlidal/protoc --js_out=import_style=commonjs,binary:. -I. ./myproto.proto

This produced:  myproto_pb.js

Now the link above says I need google-protobuf.js but that file does not exist.

I am not using Node nor gulp, so 'gulp dist' does not work.

I've tried looking at multiple threads here but none indicate where this file is.
I've downloaded protobuf-js-3.12.3.zip but it's not in there.

I want to generate protobuf messages in  a browser not from Node.

Thanks for any help





zad0m

unread,
Jul 10, 2020, 1:47:51 PM7/10/20
to Protocol Buffers
Hi Michael

I've been wondering exact same question recently, the way I found it was to:

`yarn add google-protobuf`

I know you're not using Node but just use yarn (or npm i google-protobuf) to add the node_modules folder. You need `yarn init` or `npm init -y` first to make sure there's package.json otherwise the dependency won't save.

This will add the package to your node_modules

Then inside the package you'll have the google-protobuf.js file.

Hope this helps.

But the file is massive, 230KB! Because it's the full unoptimised runtime. What I've been working lately is generating a static JS file from a proto and then compiling it with Closure Compiler. That's the right way to do it, using a test file from the protobuf js project I got:

goog.require(/*depack*/ 'proto.jspb.test.Simple1');


var message = new proto.jspb.test.Simple1();
message
.setARepeatedStringList(['hello'])
message
.setAString('world')
const binary = message.serializeBinary()

This simple interface was compiled into 


/*


 Copyright The Closure Library Authors.
 SPDX-License-Identifier: Apache-2.0
*/

function f(b,a){function c(){}c.prototype=a.prototype;b.prototype=new c;b.prototype.constructor=b};function g(){this.a=[]}g.prototype.length=function(){return this.a.length};function k(b){var a=b.a;b.a=[];return a};function l(b,a,c){b=b.a;for(a=8*a+c;127<a;)b.a.push(a&127|128),a>>>=7;b.a.push(a)}
function n(b,a){var c=p;if(null!=a){l(c,b,2);b=k(c.a);c.c.push(b);c.b+=b.length;b.push(c.b);for(var e=c.a,h=0;h<a.length;h++){var d=a.charCodeAt(h);if(128>d)e.a.push(d);else if(2048>d)e.a.push(d>>6|192),e.a.push(d&63|128);else if(65536>d)if(55296<=d&&56319>=d&&h+1<a.length){var m=a.charCodeAt(h+1);56320<=m&&57343>=m&&(d=1024*(d-55296)+m-56320+65536,e.a.push(d>>18|240),e.a.push(d>>12&63|128),e.a.push(d>>6&63|128),e.a.push(d&63|128),h++)}else e.a.push(d>>12|224),e.a.push(d>>6&63|128),e.a.push(d&63|
128)}a=b.pop();for(a=c.b+c.a.length()-a;127<a;)b.push(a&127|128),a>>>=7,c.b++;b.push(a);c.b++}};function q(){}var r="function"==typeof Uint8Array,t=Object.freeze?Object.freeze([]):[];function u(b){var a=b.c+b.f;b.a[a]||(b.b=b.a[a]={})}function v(b){var a=w;if(b<a.c){b+=a.f;var c=a.a[b];return c===t?a.a[b]=[]:c}if(a.b)return c=a.b[b],c===t?a.b[b]=[]:c}function x(b,a){var c=w;b<c.c?c.a[b+c.f]=a:(u(c),c.b[b]=a)}q.prototype.toString=function(){return this.a.toString()};function y(b){var a=b;b=z;a||(a=[]);this.f=-1;this.a=a;a:{if(a=this.a.length){--a;var c=this.a[a];if(!(null===c||"object"!=typeof c||Array.isArray(c)||r&&c instanceof Uint8Array)){this.c=a- -1;this.b=c;break a}}this.c=Number.MAX_VALUE}if(b)for(a=0;a<b.length;a++)c=b[a],c<this.c?(c+=-1,this.a[c]=this.a[c]||t):(u(this),this.b[c]=this.b[c]||t)}f(y,q);var z=[2];var w=new y;x(2,["hello"]);x(1,"world");var p=new function(){this.c=[];this.b=0;this.a=new g},A;A=v(1);null!=A&&n(1,A);A=v(2);if(0<A.length){var B=A;if(null!=B)for(var C=0;C<B.length;C++)n(2,B[C])}A=v(3);if(null!=A){var D=A;null!=D&&(l(p,3,0),p.a.a.push(D?1:0))}for(var E=new Uint8Array(p.b+p.a.length()),F=p.c,G=F.length,H=0,I=0;I<G;I++){var J=F[I];E.set(J,H);H+=J.length}var K=k(p.a);E.set(K,H);p.c=[E];console.log(E);



With advanced optimisations, which is just 2.1KB. 

My assumption is that you wouldn't want 230KB runtime so the compilation strategy is what you're after... So I'll be preparing a guide on how to do that for my website, you can add me on keybase so I'll post it to you, or I'll submit to the newsletter too. 

There's also https://www.npmjs.com/package/protobufjs library which allows to generate static js code too and their runtime is 20kb. It's also 7 times faster than google's but I don't like it because I can't compile their code and it installs hell of a lot of dependencies. They cheat npm dependency count as they have only < 10 specified in package.json, but once you start compiling protos it will pull uglify etc so you'll end up with hundreds of deps. Speed is not a factor for me I'm just looking into RPC API implementation instead of rest, and protobufs also provide message hiding so that people can't inspect network requests.

Best regards, 
Ned. 

guydi...@gmail.com

unread,
Oct 2, 2020, 1:59:16 PM10/2/20
to Protocol Buffers
I was only using Protobuf in the browser for a prototyping tool so I wasn't worried about size of performance.
This is what I ended up doing, in case someone else needs to do the same.
This was based on Ned's response above.

Red text is based on your environment and will be different.
c15985d76a6b was my docker image ID yours will be different.
~/user/BOB will be different, that is the directory you are in.

These commands should only need to be performed once:

    # to get google-protobuf.js
    #
    docker run -v $(pwd):$(pwd) -w $(pwd) node yarn add google-protobuf

    # create a link to the required file (you could copy it instead)
    #
    ln -s ./node_modules/google-protobuf/google-protobuf.js google-protobuf.js

    # pulled node/browserify docker container
    #
    docker pull tjaart/browserify-docker

    # run bash in the container image and install browserify
    #
    docker run -it -v $(pwd):$(pwd) -w $(pwd) c15985d76a6b  /bin/bash
    root@98a84580ee6b:~/user/BOB# npm install -g browserify
    root@98a84580ee6b:~/user/BOB# browserify --version
    16.5.1
    root@98a84580ee6b:~/user/BOB# exit


That's the environment set up.

As I modified my Protobuf definition during development I would run the following two commands to rebuild.
Note fcefaeaf5bdf was my docker image ID yours will be different.

    docker run --rm --user "$(id -u):$(id -g)" -v $(pwd):$(pwd) -w $(pwd) gwihlidal/protoc --js_out=import_style=commonjs,binary:. -I. ./my.proto
    docker run -it -v $(pwd):$(pwd) -w $(pwd) fcefaeaf5bdf browserify my_pb.js > my_combined.js

The file my_combined.js is what you need to use in your HTML.

    <script src="my_combined.js" type="text/javascript"></script>

You do not need to include my_pb.js because that's all wrapped up inside my_combined.js.

I hope that helps someone.

Cheers
Reply all
Reply to author
Forward
0 new messages