angular / clutz

Closure to TypeScript `.d.ts` generator
MIT License
162 stars 60 forks source link

Using clutz to generate *.d.ts files for closure-library #755

Open gregbown opened 6 years ago

gregbown commented 6 years ago

Please provide some direction on use with closure-library

There are several pieces of closure library that I would like to use in Typescript, specifically in Angular. I was informed that Google uses this tool internally to accomplish this.

If this is the case can the process please be documented? or at least provide me some direction?

Ideally, a way to point it at the closure library and have it generate all the .d.ts files would be amazing.

The only file I was able to create a .d.ts file for was the closure-library/closure/goog/base.js Any file that requires another part of the lib like closure-library/closure/goog/array/array.js has "goog.require('goog.asserts');" will throw an error.

clutz closure-library/closure/goog/array/array.js -o types/closure/array/array.d.ts

throws an error ERROR - required "goog.asserts" namespace never provided

If it does not contain a require statement it throws another error ERROR - variable goog is undeclared

There is no clear way to use or understand the usage of flags like --depgraphs or --googProvides I was only able to find an example of --externs, however; this still results in an error and there is no clear way to move forward

clutz closure-library/closure/goog/string/string.js -o types/closure/string/string.d.ts \
> --externs \
> closure-compiler/externs/es3.js \
> closure-compiler/externs/es5.js \
> closure-compiler/externs/es6.js \
> closure-compiler/externs/es6_collections.js
closure-library/closure/goog/string/string.js:24: ERROR - variable goog is undeclared
  22|  * Namespace for string utilities
  23|  */
  24| goog.provide('goog.string');
  25| goog.provide('goog.string.Unicode');
  26|

1 error(s), 0 warning(s)

Also nice to have would be documentation of gents The extent of the documentation is that it can produce the TypeScript examples shown, yet there is no description of the interface and the only thing I found is that it seems to be be accessible from the same PATH set for the clutz jar and a list of commands is available in the console. From this I was able to generate a typescript file from a closure-library file illustrated below but I am unsure if this is correct usage.

gents --convert closure-library/closure/goog/string/string.js -o out \
--root closure-library/closure/goog/ \
--externs \
    closure-compiler/externs/es3.js \
    closure-compiler/externs/es5.js \
    closure-compiler/externs/es6.js \
    closure-compiler/externs/es6_collections.js

Thank you, any assistance would be much appreciated Greg

jplaisted commented 6 years ago

With respect to generating a .d.ts file for goog.array, you need to include its dependencies. So in this case you need to include closure/goog/asserts/asserts.js and closure/goog/base.js (the latter provides goog). You'd also need to include their dependencies.

So when all is said in done the minimal command for closure/array/array.js is:

clutz \
  ./node_modules/google-closure-library/closure/goog/array/array.js \
  ./node_modules/google-closure-library/closure/goog/asserts/asserts.js \
  ./node_modules/google-closure-library/closure/goog/debug/error.js \
  ./node_modules/google-closure-library/closure/goog/dom/nodetype.js \
  ./node_modules/google-closure-library/closure/goog/base.js \
  --externs closure-compiler-master/externs/es3.js closure-compiler-master/externs/es5.js

Granted, this is not terribly user friendly to figure all of these out! I'll talk with the Angular folks and see if there isn't some better tooling we can provide here.

mprobst commented 6 years ago

I think Clutz these days should work without passing in dependencies if you tickle it with just the right command line flags.

/CC @radokirov

jimbojetlag commented 6 years ago

@mprobst would you be able to comment on this? The subject is how Clutz and/or Tsickle should be used to create a workflow for developing and releasing a Typescript application that depends on Closure Library. Would this be a viable workflow:

Development: Use Clutz to generate .d.ts files for Closure Library. Then use any module loaders, such as Webpack, to develop the Typescript application with no specific requirements for Closure Library (such as goog.provide dependency management). Would this work, or do we still need the Closure Library ecosystem, like depswriter.py, to be able to develop the application?

Production: Use Tsickle to transpile Typecript source codes to Closure annotated javascript files. Then use Closure Compiler ADVANCED mode for best optimizations.

So basically in development mode the app behaves like a modern app that can use modern module loaders, and in production mode the app behaves like a traditional Closure Library app via transpilation.

mprobst commented 6 years ago

The setup we use in Google is all based on the Closure module loader (goog.module). This assumption is baked into tsickle. It wouldn't be impossible to change that, but my impression is that you might get into more trouble with more moving parts here, and more differences between production and development.

I think @alexeagle is using tsickle in a setup though that emits plain ES modules, which might work in Closure Compiler as well. That's for a use case where all the code are ES modules though. tsickle does not have support for importing goog.module code from an ES module (I'm not sure how that'd look – maybe we'd just need to special case goog: imports when you're emitting ES modules?).