Conversation
MadaraUchiha
left a comment
There was a problem hiding this comment.
Just a few comments, nothing huge.
src/configuration-parser.spec.ts
Outdated
| import { ConfigurationParser } from './configuration-parser'; | ||
|
|
||
| describe('ConfigurationParser', () => { | ||
| it('should throw an error if given non-existing typewiz.json file', () => { |
There was a problem hiding this comment.
I'm not sure that it should explicitly throw an error when given a nonexistent file.
When there's no configuration, we should probably use some sane defaults.
There was a problem hiding this comment.
Makes sense, I'll default to an empty config (since this is allowed as well with a config file specified and the defaults are handled by the code using the config (instrument.ts, apply-types.ts and compiler-helper.ts)).
src/configuration-parser.ts
Outdated
| private typewizConfig: any; | ||
|
|
||
| public parse(configurationPath: string) { | ||
| const typewizConfigSchema = JSON.parse(fs.readFileSync('src/typewiz.json', { encoding: 'utf8' })); |
There was a problem hiding this comment.
While we do have sync IO in other places, it's generally where it's totally guaranteed that it's in the first tick (i.e. it's a CLI, or it's at the very start of a program running).
There's no such guarantee here, it might be better to use util.promisify() on fs.readFile and async/await.
There was a problem hiding this comment.
Right now ci runs against node 6.4.0 which doesn't have util.promisify() (async await should be transpiled by typescript). Is support for node 6 important or can we use util.promisify() (and then remove node 6 from ci since it wont work anymore.
There was a problem hiding this comment.
@urish Thoughts? Node 8.9.0 is the LTS, how far back do we want to support node versions?
src/configuration-parser.ts
Outdated
|
|
||
| let typewizConfigString; | ||
| try { | ||
| typewizConfigString = fs.readFileSync(path.resolve(configurationPath), { encoding: 'utf8' }); |
There was a problem hiding this comment.
Same as the last comment, sync IO is bad in low level APIs :(
|
Very nice! I've reviewed the changes so far. Huzzah 🎉 |
src/configuration-parser.ts
Outdated
| public parse(configurationPath: string) { | ||
| const typewizConfigSchema = JSON.parse(fs.readFileSync('src/typewiz.json', { encoding: 'utf8' })); | ||
| public async parse(configurationPath: string): Promise<void> { | ||
| const readFileAsync = util.promisify(fs.readFile); |
There was a problem hiding this comment.
You should probably do this outside, promisifying is expensive and we shouldn't do it every time parse() is called ;)
There was a problem hiding this comment.
I can store it in the class but that leads to issues getting the type right: in the node types readFile is actually 4 different functions all overloading the same name (because the return type changes based on whether you specify an encoding etc.). Do you know how to write that type without having to cast it when assigning it, using it and also not using any?
There was a problem hiding this comment.
All I meant was that you move const readFileAsync = ... outside the class, so that the promisification only happens once. There shouldn't be any new typing problems (literally cut and paste line 10 to above the class ... line).
There was a problem hiding this comment.
Ah, of course :) I just made the change.
|
I added support for the config file to typewiz-webpack, usage: This only supports the instrumentation though, since typewiz-webpack doesn't apply types (it creates a json file with all gathered type information. |
|
@zoehneto I think we can drop node 6 support from the core library, and then use the polyfill just inside |
|
According to the docs of the polyfill patching the util module from typewiz-node should work but we definitely have to test that. Do you want to do the same thing with typewiz-webpack? |
|
I just implemented config support for typewiz-node (node 6 polyfill not yet included). It might be necessary to add a function to recursively search for |
|
@urish I just did the rebase. I also changed the dependency for typewiz-node and typewiz-webpack to typewiz-core instead of typewiz. |
…ode 6.4.0 in typewiz-node and typewiz-webpack through a polyfill
|
@urish I just added the polyfill to typewiz-node and typewiz-webpack and updated the node version requirement for typewiz-core. That means this PR is ready for review, I'll add the documentation once that is done. Please also take a look at the open tasks in the PR description since most of those can only be performed once this PR is merged. |
| register(); | ||
| (async () => { | ||
| if (process.argv.length > 3) { | ||
| await register({ typewizConfig: process.argv[2] }); |
There was a problem hiding this comment.
I think it will make more sense to search for the config file using the same heuristic ts-node uses for finding tsconfig.json, and if we want, we can also allow the user to override this using an optional command line argument (i.e. typewiz-node --typewiz-config filename.json my-awesome-script.ts).
Otherwise, the current behavior can be somewhat confusing - if you run typewiz-node my-awesome-script.ts the script will execute, but then if you try to pass some parameter to the script, e.g. typewiz-node my-awesome-script.ts --kittens, it will treat the script as the configuration file, and you will get an error.
WDYT?
There was a problem hiding this comment.
I think there are two things to consider here:
- typewiz.json resolution: As mentioned above we could put in a function which recursively searches for typewiz.json in parent directories. I think that certainly makes sense, especially for mocha integration where we can't specify a config file.
ts-nodeuses a typescript function for that which takes the config name as a parameter, so we should be able to use the same logic - Argument parsing: Using a proper command line argument parser would certainly make this more robust and nicer to use. The only question for me is how do we want to handle
ts-node? Currently you can just parse anyts-nodeargument totypewiz-nodeand those arguments will be passed along tots-node. Do we want to maintain this feature (perhaps by stripping all typewiz config options fromprocess.argv)?
There was a problem hiding this comment.
I see the typescript function you mentioned is exported, is it a part of the public API? can we just use it?
Regarding argument parsing, I think that stripping all typewiz config options from process.argv will do the trick. But we can skip this for now, remove the extra argument from typewiz-node and just stick with searching typewiz.json as suggested above, so we can get the PR merged sooner.
There was a problem hiding this comment.
The function is exported from the main entry point for typescript so I assume it is part of the public api.
I just added a configuration finder based on that function, it is now used by typewiz-webpack and typewiz-node. I also removed the optional argument from typewiz-node for now.
|
|
||
| public async parse(configurationPath: string): Promise<void> { | ||
| const typewizConfigSchema = JSON.parse( | ||
| await readFileAsync(path.join(__dirname, 'typewiz.json'), { encoding: 'utf8' }), |
There was a problem hiding this comment.
Since the schema is not going to change in runtime, why not read it the the beginning of the file using require('./typewiz.json') ? This will also eliminate the need for JSON.parse
|
|
||
| let typewizConfigString; | ||
| try { | ||
| typewizConfigString = await readFileAsync(path.resolve(configurationPath), { encoding: 'utf8' }); |
There was a problem hiding this comment.
How about creating an internal parseConfig() function that will take the config as an object? then we could provide parse() and parseSync() as wrappers, and use parseSync() in typewiz-core/register, so we keep the node registration API sync and simple.
There was a problem hiding this comment.
Which file do you mean with typewiz-core/register (I moved typewiz-core/node-register to typewiz-node/node-register since that is the place it is used). In general the way the configuration parser is currently used in typewiz-webpack and typewiz-node it would only make sense to provide a synchronous alternative if it was used for everything (which @MadaraUchiha explicitly didn't want in the first review).
There was a problem hiding this comment.
My bad - I meant the register() function exported by typewiz-node. The reason we need that one to be sync is for using with mocha. You use it like:
mocha -r typewiz-node/dist/register src/**/test.ts
If this would be done asynchronously, there is a race condition where mocha might start requiring .ts files before we have registered.
There was a problem hiding this comment.
Makes sense. But that does mean we have to use the synchronous parsing everywhere in typewiz-node (index.ts and node-register.ts).
There was a problem hiding this comment.
That sounds okay to me. ts-node and babel both have synchronous register methods, and as far as I can tell, they also read configuration files.
|
Thanks! Two more comments and I think we are ready to go :) |
|
Lovely, thank you so much! Merge time :) |
|
Thanks :) What do you want to do about the open tasks still left here (maybe put them in the original issue)? |
|
Sounds good! Will you be willing to tackle them as well? |
|
Certainly Schema Store, Documentation and updating the webpack demo (once the new version is relesed). Webpack type applying with config is probably a task to be tackled as part of the cli and correcting the dependency version for typewiz-core would probably best be done by you during publish. |
|
Excellent |
|
I have moved the remaining tasks to issue #31 |
Implements #31
instrumentandapplyTypes