breuleux / earl-grey

Programming language compiling to JavaScript
http://breuleux.github.io/earl-grey/
MIT License
467 stars 6 forks source link

More [concrete] examples #15

Open coffeeowl opened 9 years ago

coffeeowl commented 9 years ago

The language looks interesting but the problem is that I failed to make it work on my test browser projects. I am not sure how to make it compile for a browser, both gulp example and earlify complain about missing globals, e.g. window, document. I am also not sure how to require jquery and use it on a page. On top of that I usually use grunt and don't know much about gulp.

Given that a lot of JS based languages are used in a browser context, I think it would be good to have a couple of examples explaining how Earl can be employed there.

breuleux commented 9 years ago

Globals need to be declared explicitly:

globals:
   document, window

It says that much in the documentation, but it's a small section so maybe you missed it. I'll see what I can do to emphasize/explain it better.

You can npm install jquery and then require: jquery. Browserify will package it up for you. Alternatively, you can include jquery.js on your page and add jQuery or $ in the list of globals, since jquery will define them. Same goes if you need to define your own globals for use with an external script.

There is no grunt plugin for earl grey (as far as I know). I won't make one myself, but if someone else could, that'd be great!

Good point about the examples. I will work on an examples repo for the browser to get people started. I have a couple ideas already.

coffeeowl commented 9 years ago

OK, thanks. I missed that section indeed. Speaking of examples, does that look right to you?

task earl:
  chain gulp:
    @src{paths.earl}
    @pipe{gulp-earl{}}
    @pipe{gulp-browserify{}}
    @pipe{gulp-rename{"app.js"}}
    @pipe{gulp.dest{paths.output}}

it certainly works in a browser with my simple test page, but I am not sure if that is the most efficient way? Specifically, do I have to use earlify transform? Would it bring any benefits? And if so how can I use it with gulp? @pipe{gulp-browserify{transform = {earlify}} certainly ignores earlify and therefore doesn't work without @pipe{gulp-earl{}}

breuleux commented 9 years ago

I thought earlify would work there, but gulp-browserify is deprecated/not maintained, so maybe there's something wrong with it? Anyway, if it works, it should be fine, although you probably shouldn't rely on a deprecated package. There is advice here that you can port:

https://github.com/gulpjs/gulp/blob/master/docs/recipes/browserify-transforms.md

For what it's worth, I use something like this. It may not be the best (honestly, I as I re-read it, I rewrote half of it), it's just what I hacked together for my own usage:

require: globby, end-of-stream, vinyl-source-stream, vinyl-buffer
glob = promisify{globby}
eos = promisify{end-of-stream}
task scripts:
   require: earlify, browserify
   files = await glob{paths.earl}
   await all files each file ->
      basename = path.basename{file}[...-3]
      b = browserify{transform = {earlify}}
      b.require{file, {expose = basename}}
      chain b.bundle{}:
         @pipe{vinyl-source-stream{file}}
         @pipe{vinyl-buffer{}}
         @pipe{gulp-rename{'{basename}.js'}}
         @pipe{gulp.dest{paths.output}}
         eos{@}

It does something subtly different from you: each file in paths.earl will be made into a separate bundle, along with whatever it requires, and script.eg will be saved as script.js and exposed as the script package. Maybe you just need one bundle in which case my solution is overkill, but it's nice to have the flexibility. The eos call at the end just serves to create a Promise that can be awaited.

If you only want one bundle you can simplify by removing the await all with the each loop, the eos call, and use entries = files instead of b.require.

Another thing is that I require earlify/browserify inside the task. This spares you from requiring it when you run other tasks, so e.g. gulp sass will be a tad faster if that's all you're doing.

coffeeowl commented 9 years ago

My code didn't work for multiple modules in the src tree, I had to write temporary .js files for browserify, it currently looks like this:

task earl:
  chain gulp:
    @src{paths.earl}
    @pipe{gulp-earl{}}
    @pipe{gulp.dest{paths.output}}

task browserify < earl:
  chain gulp:
    @src{'{paths.output}/main.js'}
    @pipe{gulp-browserify{}}
    @pipe{gulp-rename{"app.js"}}
    @pipe{gulp.dest{paths.output}}

So, I think I'll use your code, thanks for suggestions