Use requirejs style for loading modules. #62

Closed
wants to merge 4 commits into
from

Conversation

Projects
None yet
2 participants

renier commented May 10, 2012

  • Remove underscore dependency by adding array utilities.
    Necessary to unhinge the library from a node-specific
    environment. Added a an array utility function to replace it
    with tests.
  • Make requirejs modules callable from Node.
    By using amddefine node module.
  • Add usage information for -format option. In preparation
    to add more formatters.
  • Make example code run against requirejs-using Cucumber now.
  • Remove browserify dependency. This was something else that
    tightly bound the library to Node.

Of note:

Had to fix circular requirejs dependencies that broke cucumber in the browser in my previous pull request. Now everything looks like it's ok. Cucumber/Jasmime tests all pass. Tested the example server page. Tested in phantomjs with dojo toolkit.

Unfortunately, the way that jasmine requires a scope object to spy on a method, prevents you from requiring a dependency directly in the requirejs scope. So you have to require a level above you so that the tests can pass. But this gets you into a circular dependency situation. Thankfully, requirejs allows for a way to resolve this at module runtime by providing a synchronous version of require() after all modules have loaded.

Removing dependency on Browserify and underscore was necessary. The problem was that it tied cucumber-js to Node. You had to run a Node server. While making it possible to run in a browser, in order to do that Browserify defines it's own set of require/define functions a'la Node (strict CommonJS) in the browser. This makes it awkward to use cucumber with other JavaScript toolkits that already have their set of AMD require/define functions. For example, require.js is one package that defines the AMD functions. Dojo is another that defines the AMD functions (based largely on require.js and 100% compatible). jQuery is also compatible with AMD and requirejs. With this, now you can take cucumber-js and run it in any server with any number of javascript toolkits that support AMD.

Owner

jbpros commented May 10, 2012

@renier I've added the requirejs branch to the official repo so that we can work together on it. Simply pull form it and push your changes back to the one on your repo.

renier and others added some commits Apr 5, 2012

Use requirejs style for loading modules.
* Remove underscore dependency by adding array utilities.
  Necessary to unhinge the library from a node-specific
  environment. Added a an array utility function to replace it
  with tests.

* Make requirejs modules callable from Node.
  By using amddefine node module.

* Add usage information for -format option. In preparation
  to add more formatters.

* Make example code run against requirejs-using Cucumber now.

* Remove browserify dependency. This was something else that
  tightly bound the library to Node.

renier commented Jul 10, 2012

For the example to work with these changes, a new cucumber-html release should be published to npm with the latest commits. Consequently, package.json here should be updated.

Owner

jbpros commented Jul 10, 2012

@renier Gotcha. Cucumber-html release on hold (see #18).

Owner

jbpros commented Sep 9, 2012

I get a segfault when running the feature suite through cucumber.js itself: https://gist.github.com/3687452

Could it be related to circular references or something?

I've also tried merging in master to get the latest changes (JSON formatter) but the segfault persists and prevents me from ensuring everything is ok.

Deploying Cucumber.js to the browser is the current priority. I've looked into other solutions to module packaging and I've got to say the current state of things is pretty depressing. Browserify is a no-go (broken, bloated and polluting global namespace) and the other tools are just not mature enough (missing features, unstable, not tested, ...).

I was pretty excited by sheperd-js but it does not seem Node.js-aware at all.

Will we have to build our own bundle system or what?

renier commented Sep 13, 2012

Hey @jbpros ,

I think an alternative would be to use something like browserify but make it define the require function under a different name, so that it doesn't clash with the module loader of choice in the web page. That could work, though I don't know how customizable things are with browserify.

I'm swamped this week, but I can take a stab at it next week if you haven't solved it (assuming the segfault is related to my requirejs branch) and at the very least update the branch against master HEAD.

Owner

jbpros commented Sep 13, 2012

I've successfully enclosed the browserify bundle in a closure and made its require() function not pollute the global namespace anymore. It's working really well (see the latest pushes on master).

However, I'm having a hard time bundling several things together for serious in-browser execution. You may know I started the Cukestall and Kite projects. Cukestall is the in-browser runner for cukejs and Kite is a capybara-like library (an abstraction layer on top of any browser simulation/automation tool).

I managed to serve them through browserify with the help of some awful dark wizardry I'm not proud of.

The thing is: browserify is deeply broken. It does not handle relative paths and external modules well. I have to use such terrible hacks to get around those issues but it's not consistent and I'm not able to expose a decent API in Kite or Cukestall because of it.

I admit I'm getting a bit desperate about this. I can't seem to find a decent way of packaging Cucumber.js, Cukestall and Kite for the browser.

Ideas are welcome.

If you could take a look at that segfault issue, it could re-open the door for the requirejs approach.

😓

Owner

jbpros commented Oct 21, 2012

Now that we don't pollute the global namespace anymore with require(), does this pull request still make sense? A requirejs-based environment wouldn't be impaired by Cucumber.js, right?

I'm considering closing this PR. Any comments?

renier commented Oct 22, 2012

@jbpros I find there is still need for this. To me, the most flexible path, is to allow the Cucumber.js files as-is to be statically pulled through an AMD loader like require.js. No node.js or browserify preprocessing needed.

In the current way, we are saying that if you want to use Cucumber in a web browser you have to use a special loader that we pre-decided on. If you want to use another for your other things, that's fine, but you are on your own if you want to integrate the two.

I actually have created a project on top of cucumber.js (my require.js branch) that loads cucumber plus features/stepDefs statically using AMD, then it can test any web application in a secondary window, while pretty printing the results in the primary window. The browsers are automatically started based on a config file, very much like testem or buster.js or jstestdriver, but of course with the unique cucumber step definitions instead.
I have in my todo to update my branch with your upstream, and then maybe I can open source what I did on top of it.

Owner

jbpros commented Jun 11, 2013

Closing this. I think having a simple Cucumber.js bundle is the best as it's a framework-agnostic approach. It's a plain JS closure that can be wrapped within any packaging system.

@renier feel free to reopen if you want to discuss it further.

@jbpros jbpros closed this Jun 11, 2013

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment