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

Inline runtime generation, fix test:browser #176

Merged
merged 5 commits into from
Apr 8, 2016

Conversation

zapu
Copy link
Collaborator

@zapu zapu commented Apr 3, 2016

Added inline runtime generation with build:inline_runtime task. The runtime is generated to extras/inline-runtime.js and is used in nodes.coffee to emit IcedRuntime, if the option is set to inline or window.

This method, however, limits compilation capabilities of iced as browser library. Iced in browser will not be able to emit inline runtime, because there will be no inline-runtime.js text file anywhere. Compiling with runtime: none and letting it use runtime from iced global variable will work - and that's what test:browser Cake task does right now.

All tests pass, for both test and test:browser. Keep in mind that test:browser runs less tests, grep testingBrowser to see which test files are skipped.

Added Cakefile task to build inline runtime (iced-runtime-3) and save it
to extras/inline-runtime.js. It is used in nodes.coffee when runtime:
'inline' is requested.
Improve IcedRuntime node to properly generate 'inline' and 'window'
runtimes. It is done by including extras/inline-runtime.js file into the
output. This file is generated with Cakefile build:inline_runtime task.

Fix browser tests. When in test:browser task, test files will be
compiled with runtime set to 'none'. `global.iced` will point to
iced-runtime instead. This is done to simulate browser environment.

unless process.env.MINIFY is 'false'
{code} = require('uglify-js').minify code, fromString: true

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Can someone check if uglifying works? It fails for me in both build:browser and build:inline_runtime with parse errors.

Copy link
Owner

Choose a reason for hiding this comment

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

Yeah, no dice: mishoo/UglifyJS#448

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Aww, so it's related to es6 features? Ok...

Copy link
Owner

Choose a reason for hiding this comment

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

Yeah, seems to be puking on function*

Copy link
Owner

Choose a reason for hiding this comment

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

Talking to @chrisnojima about this in the office, we probably shouldn't be outputting ES6 to browsers anyways. People should convert to ES6 via babel (or whatnot). This is of course a much deeper concern, and indicates a deeper change in workflow, so maybe we shouldn't spend too many cycles on this.

Copy link
Owner

Choose a reason for hiding this comment

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

However, if we did, it still wouldn't change the fact that the actual code emittted from iced3 is in ES6 (with function*) and will break many browsers.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

But this is the point of this branch, no? To emit ES6 for future browsers or as input for babel translation.

We can optionally support browserify in compiler - but do not actually specify it as a dependency - so it will simplify the workflow for people who have it installed anyways.

Copy link
Owner

Choose a reason for hiding this comment

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

Agreed all around. Probably the most useful workflow is for us to output ES6, and then for consumers of the output code to minify and transpile as they see fit. Meaning, the whole direct browser operation of CoffeeScript might be moot for us, or more charitably, best-effort.

Copy link
Owner

Choose a reason for hiding this comment

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

In sum, let's stick with the previous plan of (1) outputting the inline-runtime via raw string inclusion, and add (2) disabling of minification

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Cool, thanks! I have (1) almost done but I need to write some tests. I'll try to have it all committed here at the end of the day.

@zapu
Copy link
Collaborator Author

zapu commented Apr 6, 2016

So what are we doing with this one?

@zapu
Copy link
Collaborator Author

zapu commented Apr 6, 2016

About require('fs') in browser - I think you removed the comment while I was typing the reply. It might be useful anyways:

That's correct, this would be a limitation of the compiler in browser for now. It wouldn't be able to compile code with runtime set to 'inline'. I don't really see a good way around it.

I tried to make the compiler "decompile" it's own runtime and emit it, but it led to nowhere. I can try this again if it sounds like a reasonable solution to you.

@@ -2437,6 +2438,10 @@ class IcedRuntime extends Block
if @isEmpty() then []
else super o

inlineRuntime: (lefthand) ->
fs = require('fs')
Copy link
Owner

Choose a reason for hiding this comment

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

My only frustration is that we used to have something that did work here. So how do you think the browser compiler should work then --- the user has to insert their own runtime? I'm getting a little confused.

@maxtaco
Copy link
Owner

maxtaco commented Apr 6, 2016

Here's an idea I had:

  • In the cake build:inline-runtime step, output a lib/coffee-script/inline-runtime.js file that has the code from inline-runtime.js in a raw string
  • Emit the raw string on compilation in inline mode, instead of reading the file off of the fs via require('fs'). So instead, something of the form:
inlineRuntime: (lefthand) ->
    inline_runtime = require('./inline-runtime).runtime
    "#{lefthand} = #{inline_runtime};"

@zapu
Copy link
Collaborator Author

zapu commented Apr 6, 2016

OK, that was another idea that I've had before. I wasn't sure which one was better - decompiling or saving raw string. So I'll get to it later today.

@zapu
Copy link
Collaborator Author

zapu commented Apr 6, 2016

Just for reference (and for other people interested, maybe), iced2 used to do this: https://github.com/maxtaco/coffee-script/blob/iced2/src/nodes.coffee#L3394 which was not ideal either.

@maxtaco
Copy link
Owner

maxtaco commented Apr 6, 2016

(I editted my comment above, thank you @zapu!)

@maxtaco
Copy link
Owner

maxtaco commented Apr 6, 2016

Indeed, the previous solution was bad for several reasons, especially because the code was different/worse and drifted further apart over time.

zapu added 2 commits April 7, 2016 11:02
Inline runtime will now contain stringified copy of itself. This is done
in order to be able to emit the runtime from a browser-based compiler
(or any environment that does not have a filesystem or access to
compiler files).

Removed uglifyjs support as it did not work with ES6 code.

Renamed "build:inline_runtime" task to "build:inline-runtime"
@zapu
Copy link
Collaborator Author

zapu commented Apr 7, 2016

I added the commit, it's still pretty rough around the edges, but the tests pass and seems OK overall.

Stringified inline runtime is now accessible via
require('./inline-runtime-str') from both node version and the browser.
Much cleaner solution than the previous one.
@zapu
Copy link
Collaborator Author

zapu commented Apr 7, 2016

Changed this approach a little bit to be more lined up with your proposal, and removed irrelevant comments from this PR. Things are much cleaner right now.

I should also squash the commits before eventual merge.

@maxtaco
Copy link
Owner

maxtaco commented Apr 8, 2016

Looking very good. Do you get all tests passing? I'm still seeing one failing (repl.coffee:69).

@maxtaco
Copy link
Owner

maxtaco commented Apr 8, 2016

 node ./bin/cake test

failed 1 and passed 714 tests in 2.58 seconds 

  empty command evaluates to undefined 
  AssertionError: Expected undefined to equal iced> 
  at global.eq (/Users/max/src/iced/coffee-script/Cakefile:363:14)
  at /Users/max/src/iced/coffee-script/test/repl.coffee:69:3
  at Function.<anonymous> (/Users/max/src/iced/coffee-script/test/repl.coffee:38:17)
  at global.test (/Users/max/src/iced/coffee-script/Cakefile:287:12)
  at testRepl (/Users/max/src/iced/coffee-script/test/repl.coffee:38:3)
  at Object.<anonymous> (/Users/max/src/iced/coffee-script/test/repl.coffee:67:1)
  at Object.<anonymous> (/Users/max/src/iced/coffee-script/test/repl.coffee:1:1)
  at Module._compile (module.js:409:26)
  at Object.exports.run (/Users/max/src/iced/coffee-script/lib/coffee-script/coffee-script.js:136:23)
  at runTests (/Users/max/src/iced/coffee-script/Cakefile:412:22)
  at Object.action (/Users/max/src/iced/coffee-script/Cakefile:429:12)
  at helpers.extend.invoke (/Users/max/src/iced/coffee-script/lib/coffee-script/cake.js:44:26)
  at Object.exports.run (/Users/max/src/iced/coffee-script/lib/coffee-script/cake.js:70:20)
  at Object.<anonymous> (/Users/max/src/iced/coffee-script/bin/cake:7:38)
  at Module._compile (module.js:409:26)
  at Object.Module._extensions..js (module.js:416:10)
  at Module.load (module.js:343:32)
  at Function.Module._load (module.js:300:12)
  at Function.Module.runMain (module.js:441:10)
  at startup (node.js:134:18)
  at node.js:962:3

  function () {
      return fn(input, output, repl);
    }

@zapu
Copy link
Collaborator Author

zapu commented Apr 8, 2016

Hm, there was a change in behavior in node but I'm no longer seeing that. I tried to make this change in upstream (jashkenas#4120) but it wasn't accepted. What node version do you have? I'll try to find some time and dig through the changelogs.

Can you try something like this?

zapu@lab » node
> undefined
undefined
> console.log('hell')
hell
undefined
>
zapu@lab » node --version
v5.6.0

Also, what's with the versions? I guess their versioning changed after all the node.js/io.js things happened.

@maxtaco
Copy link
Owner

maxtaco commented Apr 8, 2016

Ah, I'm running 4.3.2....

@zapu
Copy link
Collaborator Author

zapu commented Apr 8, 2016

The correct way would be to detect repl settings (because I think you can change the undefined behavior) and make test check result according to this setting.

@maxtaco
Copy link
Owner

maxtaco commented Apr 8, 2016

Well still broken for me on 5.10.1., but that's ok.

👍 Ok, to merge!

@maxtaco maxtaco merged commit 5e1d887 into maxtaco:iced3 Apr 8, 2016
@zapu
Copy link
Collaborator Author

zapu commented Apr 8, 2016

Oh, cool! Thanks!

@maxtaco
Copy link
Owner

maxtaco commented Apr 8, 2016

Thank you!

@zapu zapu deleted the extras_inline_runtime branch May 12, 2018 10:44
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

2 participants