webjars / d3js

5 stars 4 forks source link

d3 shim not correctly exported #8

Closed muuki88 closed 10 years ago

muuki88 commented 10 years ago

I'm using the current version, but the d3 global variable isn't exported.

The config looks like this

// webjar config for d3js
requirejs.config({
    paths: { "d3js": webjars.path("d3js", "d3") },
    shim: { "d3js": { "exports": "d3" } }
});

I'm running on play 2.2.2 and the current webjars version.

Using

define(['d3js'], function(d3) {

}

works. But doesn, when I use nvd3 as this expects d3 in the global namespace.

jamesward commented 10 years ago

How are you setting up the RequireJS stuff?

muuki88 commented 10 years ago

I'm using a very basic play setup.

My app.js looks like this

require(['d3js', 'nvd3'], function(d3, nv) {
    // enough to produce the exception
});

my build.sbt is very plain, too

name := "activator-play-requirejs"

version := "1.0-SNAPSHOT"

libraryDependencies ++= Seq(
  jdbc,
  anorm,
  cache,
  "org.webjars" %% "webjars-play" % "2.2.1-2",
  "org.webjars" % "d3js" % "3.4.6",
  "org.webjars" % "nvd3" % "1.1.15-beta-1"
)     

play.Project.playScalaSettings

My main.scala.html is more or less the basic template

<html>
    <head>
        <title>@title</title>
        <link rel="stylesheet" media="screen" href="@routes.Assets.at("stylesheets/main.css")">
        <link rel="shortcut icon" type="image/png" href="@routes.Assets.at("images/favicon.png")">
        @Html(org.webjars.play.RequireJS.setup("js/app"))
    </head>
    <body>
        @content
    </body>
</html>
jamesward commented 10 years ago

I'm not a RequireJS expert but I wonder if this is a timing thing. Sounds like you need to first load d3js then load nvd3. The nvd3 RequireJS config should be doing this automatically for you as long as you do:

require([nvd3'], function(nv) {

I think that putting both of the resources in that require will load them in an indeterminate order.

muuki88 commented 10 years ago

It seems to be the order in which the requirejs.config({}) calls are made. If I use

@Html(org.webjars.play.RequireJS.setup("js/app"))

the order is

requirejs.config({
    paths: { "nvd3": webjars.path("nvd3", "nv.d3") },
    shim: { 
        'nvd3':  { 
            'deps' : [ 'd3js'],
            'exports': 'nv'
        } 
    }
});

requirejs.config({
    paths: { "d3js": webjars.path("d3js", "d3") },
    shim: { "d3js": { "exports": "d3" } }
});

which doesn't work. However if I add this manually and swap the order, everything works. This maybe an issue in the play-webjars plugin. Looks like requirejs cares about the order.

jamesward commented 10 years ago

Ah... It looks like d3 is not compatible with the RequireJS shim exports. See: http://stackoverflow.com/questions/13157704/how-to-integrate-d3-with-require-js#comment32647365_13171592 https://github.com/mbostock/d3/issues/1693

One possible workaround without messing with the RequireJS config:

require(['d3js'], function(d3) {
  window.d3 = d3;
  require(['nvd3'], function(nvd3) {
    console.log(nvd3);
  });
});
geralddejong commented 10 years ago

Ah brilliant, that did the trick. Mille grazie!

muuki88 commented 10 years ago

Which one? The stackoverflow answer just describes how requirejs works with non-requirejs librarys and webjars-play does everything correctly.

jamesward commented 10 years ago

The workaround I posted should suffice.

mariussoutier commented 9 years ago

After playing around a bit more, the dual-require poses some problems when optimizing. So I switched to the approach suggested in the 'official' answer using the d3.global hack.