Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Document side-effects free programmatical usage #93

Closed
medikoo opened this issue Jul 11, 2017 · 10 comments
Closed

Document side-effects free programmatical usage #93

medikoo opened this issue Jul 11, 2017 · 10 comments

Comments

@medikoo
Copy link
Contributor

medikoo commented Jul 11, 2017

I'd like to use this package programmatically in a script (to recompile some JS files), but with no side effects (e.g. extending natives prototypes or messing with Node.js require system).

The best I probably can get is via:

const nodent = require('nodent')({
  augmentObject: false,
  dontMapStackTraces: true,
  dontInstallRequireHook: true,
});

const compiledSourceCode = nodent.compile(sourceCode, filename, {
  promises: true,
  es7: true,
  noRuntime: true,
  es6target: true,
}).code;

Still if I read correctly, it still implies some side effects:

Is there any chance to obtain a clean run programmaticaly?

@matAtWork
Copy link
Collaborator

Short answer, not at the moment, however with the appropriate compile options, such a change could be made - I'll have a go in the next few days. It will restrict the compilation targets; requiring noRuntime and Promises, and would prevent the use of ES7-mode and generators, both of which require runtime support.

You can control the names of the modifications, which should allow you to avoid clashes.

You can also compile via the './nodent.js' script (with the --output option) in a seperate process, which obviously won't modify your runtime.

Is this what you're trying to achieve?

@medikoo
Copy link
Contributor Author

medikoo commented Jul 11, 2017

Is this what you're trying to achieve?

Yes, ideally I want to handle compilation of async/await in scripts which do also other things, and I would prefer that individual tasks do not "leak" undesired changes outside (especially that in that specific case of nodent usage, there's no need for environment changes)

Thanks for answering!

@matAtWork
Copy link
Collaborator

Just had a quick look, and right now this is a bit of a mess for legacy reasons. I could possibly provide a secondary "compileOnly" module (as in var compiler = require('nodent/compileOnly'); which would avoid all the legacy guff, but it'll take me a little while. If that works for you, let me know and I'll have a go when I can

@medikoo
Copy link
Contributor Author

medikoo commented Jul 11, 2017

Just had a quick look, and right now this is a bit of a mess for legacy reasons. I could possibly provide a secondary "compileOnly" module (as in var compiler = require('nodent/compileOnly');

Yes, that would be great.

I think it'll be also possible (but not in a clean, straightforward way) if NodentCompiler would be exposed on exported initialize function. Then I guess it'll be possible to setup compiler without calling setGlobalEnvironment ?

@matAtWork
Copy link
Collaborator

Actually, that's (also) historic - the Function.prototypes are set in the nodent-runtime module, which is used by a number of third-party apps, so I need a different entry-point to avoid breaking other people's projects.

@matAtWork
Copy link
Collaborator

I've pushed a new branch which extracts the compiler into a new file which has no runtime dependency or pollution. It's not published yet, so update your project with:

npm install git://github.com/MatAtBread/nodent#extract-compiler (--save if you want to)

With this revision, you can require nodent/compiler which skips all the runtime inclusion and initialisation.

I have a little test file:

var NodentCompiler = require('nodent/compiler') ;
var c = new NodentCompiler() ;
console.log(c.compile("async () => 1+await x",null,null,{ sourcemap:false, promises: true, noRuntime: true, es6target: true })) ;

Note that it does_not respect the use nodent directive (or package.json options) - it requires you to pass the options in the final parameter of the call to compile(). After all, it's just a compiler. Note also that the code it produces will require nodent-runtime to be present unless you have specified the noRuntime options when compiling. The example above does just that, so the compiled code should run just about anywhere Promises exist.

If this meets your requirements, let me know and I'll do a little tidying up and publish on npm. I'm happy to receive a PR to on that branch to document the new feature too!

@medikoo
Copy link
Contributor Author

medikoo commented Jul 11, 2017

Thanks @matAtWork, looks great. I've tried my best in updating documentation at: #94
Still you will probably want to fine tune that

@matAtWork
Copy link
Collaborator

NP. I may well actually separate the CLI, from the core compiler mainly as I like clean dependencies, and the compiler has no dependency on nodent-runtime (and some other stuff like resolve), although as stated it can generate code that does depend on nodent-runtime.

I need to run some further tests and make sure I don't other people's stuff, but hopefully I'll have this ready to go tomorrow. When I have, I'll remove the branch and publish via npm as normal.

@matAtWork
Copy link
Collaborator

The compiler has been shipped as the npm module 'nodent-compiler', which has no runtime or global side-effects. 'nodent' has been updated to refer to the compiler as a sub-module, leaving it purely for running the CLI and require hook mechanism. Shipped in https://github.com/MatAtBread/nodent/releases/tag/3.1.0

@medikoo
Copy link
Contributor Author

medikoo commented Jul 12, 2017

Looks great, thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants