Skip to content
This repository has been archived by the owner on Aug 7, 2019. It is now read-only.

Pass require.config() data or app.build.js file to jam compile #127

Open
nfriedly opened this issue Jan 23, 2013 · 12 comments
Open

Pass require.config() data or app.build.js file to jam compile #127

nfriedly opened this issue Jan 23, 2013 · 12 comments

Comments

@nfriedly
Copy link
Contributor

Short version:

I'm using a hbs! plugin that's not in jam. I define the path in a require.config() call at the top of my main init.js file, but when I run jam compile, it doesn't parse that config and doesn't know the path to the plugin, and then chokes when the plugin gets called. How can I tell jam compile about that path?

Long version:

This is the start of my main init.js file:

require.config({
    hbs: {
        disableI18n: true,
        // write "templatename.handlebars" - this is required because we have some templates with the same name as .js
        // files and require.js gets confused since the normalized hanes have no file extension
        templateExtension: false
    },
    // todo: delete this once hbs is available in jam https://github.com/SlexAxton/require-handlebars-plugin/issues/79
    paths: {
        "hbs": "lib/require-handlebars-plugin/hbs",
        "handlebars": "lib/require-handlebars-plugin/Handlebars",
        "json2": "lib/require-handlebars-plugin/hbs/json2",
        "i18nprecompile":  "lib/require-handlebars-plugin/hbs/i18nprecompile"
    },
    baseUrl: "/scripts"
});

define([...

When I do my jam compile, I include that file first, but jam doesn't execute the file, so it never gets the configuration info from it. Then it chokes when looking for the hbs! plugin because it doesn't know the path to it.

This is the command I run:

jam compile -v --almond --wrap --out out/CUSTOMER_NAME.min.js -i CUSTOMER_NAME_config.js -i init.js -i modules/gallery/gallery -i modules/connector/connector -i modules/fblike/fblike -i modules/welcome/welcome -i modules/popularmos/popularmos -i modules/streampublish/streampublish -i modules/activitystream/activitystream

And this is the output from that command:

compiling out/CUSTOMER_NAME.min.js
include CUSTOMER_NAME_config.js, init.js, modules/gallery/gallery, modules/connector/connector, modules/fblike/fblike, modules/welcome/welcome, modules/popularmos/popularmos, modules/streampublish/streampublish, modules/activitystream/activitystream
using almond.js

Tracing dependencies for: requireLib
Error: ENOENT, no such file or directory '/usr/local/SociableLabs/1.553f5b0/conductor/webapps/rondavu.war/scripts/hbs.js'
In module tree:
    modules/gallery/gallery

Error: ENOENT, no such file or directory '/usr/local/SociableLabs/1.553f5b0/conductor/webapps/rondavu.war/scripts/hbs.js'
In module tree:
    modules/gallery/gallery

    at Object.fs.openSync (fs.js:338:18)

Failed

That hbs.js file it's choking on is actually located at /usr/local/SociableLabs/1.553f5b0/conductor/webapps/rondavu.war/scripts/lib/require-handlebars-plugin/hbs.js and it loads correctly when I'm running non-compiled js.

I've looked into this a little and found that r.js (which I think jam uses under the hood) has a -o app.build.js config flag where the app.build.js file includes this info. But with jam, the -o flag specifies the output file. (I tried it anyways, but it still failed with the same error. I assume if it had been successful, it would have overwritten my app.build.js file.)

Is it possible to do this with jam? If not, would you be willing to add this feature? I think if #95 were done, that would do the trick too.

@nfriedly
Copy link
Contributor Author

I've been thinking about this for a while, trying to come up with a way that doesn't involve duplicating your configs or editing the files in jam/ and I have a proposal: Add a new field to the top-level package.json with extra config options for require.js. Then any time jam rebuilds the jam/require.js and jam/require.config.js files, it automatically merges in this config if it exists. And, when jam compile is run, this config is included there too.

I'm thinking jam.requireconfig for the package.json field name, but I'm open to suggestions.

What do you say to this? I'd be happy to code it up if there's some chance that a pull request would be accepted.

@caolan
Copy link
Owner

caolan commented Feb 5, 2013

@nfriedly yes, I think a property in package.json is the way to go in this case :)

@nfriedly
Copy link
Contributor Author

nfriedly commented Feb 7, 2013

Cool, I'll get working on it as soon as I have the chance.

@nfriedly
Copy link
Contributor Author

nfriedly commented Mar 1, 2013

BTW, I think this is done - see https://github.com/nfriedly/jam/tree/extraconfig, but the compile test is failing. It looks like it's the same root cause as #134

@heme
Copy link

heme commented Mar 13, 2013

I believe that I'm running into a related issue...

Shim dependencies in the config section of my package.json are being overwritten by jamjs. This specifically happens when I try to use lodash for backbone instead of underscore.

My package.json:

  • Redefine backbone's deps as lodash & jquery instead of underscore & jquery
  • Underscore is not included in the project anywhere
{
  "jam": {
    ...
    "config": {
      ...
      "packages": [
        {
          "name": "lodash",
          "location": "./libs/jam/lodash/",
          "main": "dist/lodash.underscore.js"
        }
      ],
      "shim": {
        "lodash": {
          "exports": "_"
        },
        "backbone": {
          "deps": [
            "lodash",
            "jquery"
        ],
          "exports": "Backbone"
        }
      }
    }
  }
}

Jam's require.config output:

  • backbone's deps are now underscore & jquery
  • lodash is not a dep of backbone
  • lodash listed 2 times in packages (mine and Jam's)
require.config({
    ...
    "packages": [
        {
            "name": "lodash",
            "location": "./libs/jam/lodash/",
            "main": "dist/lodash.underscore.js"
        }
        {
            "name": "backbone",
            "location": "libs/jam/backbone",
            "main": "backbone.js"
        },
        {
            "name": "lodash",
            "location": "libs/jam/lodash",
            "main": "./lodash.js"
        },
        {
            "name": "underscore",
            "location": "libs/jam/underscore",
            "main": "underscore.js"
        }
    ],
    "shim": {
        "lodash": {
            "exports": "_"
        },
        "backbone": {
            "deps": [
                "underscore",
                "jquery"
            ],
            "exports": "Backbone"
        },
        "underscore": {
            "exports": "_"
        }
    }
});

I apologize if this is designed functionality. However, I'd rather not load a separate require.config if possible. I assume that causes problems when optimizing/building.

I will try to debug, but this is my first time jumping in with an NPM module. I'm still learning; any advice is appreciated. Thanks for all your hard work.

@nfriedly
Copy link
Contributor Author

hum.. I was under the impression that that only applied to packages in the jam repository and not your top-level package.json for your project. But the docs don't seem to say that.

I have a separate branch I'm working on for the top-level stuff, but I'm not satisfied with it yet. Maybe I need to look into this a bit more and possibly rework my branch.

@heme
Copy link

heme commented Mar 15, 2013

Not sure. I'm not seeing the config section in the docs on the site, but I did notice it in README and issue discussion.

When including backbone, I assume jam is managing all the dependencies for backbone. However, I would expect that adding a config -> shim -> backbone in my project's package.json would tell jam to use my redefined settings/dependencies.

Is this assumption wrong? Does it always use Backbone's package.json -> jam -> shim -> deps from the jam repository?

Sounds like #117 might be related as well?

@CameronJ
Copy link

Any updates on this issue? I'm really just looking to be able to support passing a "baseUrl" through to require.config.js. I understand that JAM needs it's own packageDir and baseUrl to know things about site root, etc, but I really would prefer not to need to call every js file by doing:

require(["/assets/js/test.js"], function(){});

Putting the path seems a little redundant, when require.js already has the baseUrl functionality supported.

While it might not be accurate, it seems like development has gone a little stagnant on this repository, surprised that this issue hasn't been resolved in 2 years.

@CameronJ
Copy link

As an FYI, I've come up with a temporary solution for the problem... not a great solution, but it does seem to work (at least thus far).

First, my folder structure is built in the following format:

  • views
    • assets
      • js
        • lib
          • jquery [example package]
          • require.config.js
          • require.config.override.js [described below]
          • require.js
        • test.js
"jam": {
    "packageDir": "views/assets/js/lib",
    "baseUrl": "views/assets/js"
}

To temporarily solve for this problem, I created the require.config.override.js file with the following contents:

var config = requirejs.s.contexts._.config;
config.baseUrl = "/assets/js/";

requirejs.config(config);

Then, on the page, I've included 2 script files:

<script language="JavaScript" type="text/javascript" src="/assets/js/lib/require.js"></script>
<script language="JavaScript" type="text/javascript" src="/assets/js/lib/require.config.override.js"></script>
<script type="text/javascript">
    require(["test"], function(){
        console.log("loaded");
    });
</script>

First, I realize that this is a bit of a hack, and not exactly a good solution; however, I'm all ears for a better solution.

[edit: I accidentally hit comment, before I finished writing it, updated with the missing content]

@nfriedly
Copy link
Contributor Author

Sorry, I know I started this and then kind of abandoned it. I was hoping that I'd get a chance to send a PR, but I no longer work in that position and don't really use jam or require.js for much these days.

I'm pretty sure that they just got a hack similar to yours in place and left it at that.

@CameronJ
Copy link

@nfriedly Thanks for replying! Do you happen to recall what issues you had with your code? Or more accurately, how significant a fix would be? Worth asking, but I'm not really familiar with the JAM code base; however, I'd love to see it finished, and might be willing to do it myself... I'm just looking to start using JAM, as I have a real requirement for Require.JS, which server side dependency injection (like browserify) cannot solve for, and JAM seems like the best solution for handling dependencies with Require.JS, especially when a private (corporate) repository has been added.

@nfriedly
Copy link
Contributor Author

Yea, it's been a couple of years and I don't remember so much now. Looking through the history here, it looks like I modified one of the other packages to work without any configuration, and then also modified JAM a bit - see https://github.com/nfriedly/jam/commits/extraconfig

However, that's so outdated that I'm not sure if it's still relevant.

yoyooli8 pushed a commit to yoyooli8/require-handlebars-plugin that referenced this issue Jun 22, 2016
…e-handlebars-plugin#79 although there's no way to configure it for jam compile at the moment - see caolan/jam#127 ). This commit keeps the dependencies included in the package, although we could update it to use jam-provided coppies of underscore and json2 (and possibly handlebars)
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants