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

Fixes Node.js compilers writing to STDOUT and/or STDERR during compilation #42

Closed

Conversation

alexgorbatchev
Copy link

This was happening when I was trying to compiler an Ember template with Rails Assets that had deprecation warnings. The warnings would be printed to STDOUT and end up being part of the string that was going to be JSON parsed.

@rails-bot
Copy link

Thanks for the pull request, and welcome! The Rails team is excited to review your changes, and you should hear from @arthurnn (or someone else) soon.

If any changes to this PR are deemed necessary, please add them as extra commits. This ensures that the reviewer can see what has changed since they last reviewed the code. Due to the way GitHub handles out-of-date commits, this should also make it reasonably obvious what issues have or haven't been addressed. Large or tricky changes may require several passes of review and changes.

Please see the contribution instructions for more information.

@@ -376,4 +376,30 @@ def test_uglify
assert_equal "function foo(bar){return bar}",
context.call("uglify", "function foo(bar) {\n return bar;\n}")
end

def test_compiler_writing_to_stdout

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe stdio instead of stdout since this is testing both stdout and stderr?

@arthurnn
Copy link
Member

arthurnn commented Jun 2, 2016

@rafaelfranca @josh @SamSaffron thoughts?

@josh
Copy link
Contributor

josh commented Jun 2, 2016

I'd suggest process be simply undefined.

https://github.com/rails/execjs/blob/master/test/test_execjs.rb#L232-L257

@eventualbuddha
Copy link

@josh that won't work for us, in this case. Ember is using new Function('return this') to get the actual global object and getting console off that. Calling e.g. console.log then delegates to process.stdout.write, hence the approach with this PR.

@josh
Copy link
Contributor

josh commented Jun 3, 2016

Ember is using new Function('return this') to get the actual global object and getting console off that. Calling e.g. console.log then delegates to process.stdout.write, hence the approach with this PR.

Then Ember is going to crash running in any environment that isn't node. In JSC typeof process === 'undefined', in therubyracer typeof process === 'undefined'.

@eventualbuddha
Copy link

No, it won't crash because it never references process directly. It has no need to.

  1. Ember gets the global object using new Function('return this').
  2. It then uses the global as context.imports exported by ember-environment :
export const context = {
  // import jQuery
  imports: originalContext.imports || global,
  // export Ember
  exports: originalContext.exports || global,
  // search for Namespaces
  lookup: originalContext.lookup || global
};
  1. It gets context.imports.console in ember-console and uses it to build functions that wrap the real console functions.
  2. Finally, the console methods in node delegate to stdout and stderr properties passed to the constructor, which are process.stdout and process.stderr.

In other environments console is implemented differently or not at all. If there is no console, Ember simply uses an empty function for the logging methods. This PR tries to prevent any output, regardless of whether it comes from the console object or via direct access to process. The wrapper function that shadows references to globals is not enough.

Does it make sense now?

@josh
Copy link
Contributor

josh commented Jun 5, 2016

Ember gets the global object using new Function('return this').

If it was possible, it'd be great if new Function('return this')() was normalized across environments. But like you mentioned, shadow eval's scope.

I still think we should attempt to undefine as much of process as possible during evaluation. process.stdout.write shouldn't be a noop, but undefined.

@josh
Copy link
Contributor

josh commented Jun 6, 2016

@eventualbuddha Does #43 work in the eval case?

@eventualbuddha
Copy link

I believe so. I'll leave it to @alexgorbatchev to check.

@alexgorbatchev
Copy link
Author

I just tested locally, #43 also addresses this issue.

@rafaelfranca
Copy link
Member

Closing this one since #43 was merged. Thanks for the contribution.

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

Successfully merging this pull request may close these issues.

None yet

6 participants