GithubHelp home page GithubHelp logo

Comments (7)

unscriptable avatar unscriptable commented on August 24, 2024

Hey Tom,

There are some serious limitations to using that syntax in 0.5.x. It works, but it's not useful as it is in 0.6, which I am trying to get released this week. In a nutshell, here's how it will work:

Getting the local require function:

You can grab a reference to the local require function (and the other CJS "free" variables) in any module in one of two ways.

  1. if a module has no dependencies and uses definition function (aka factory function) with parameters it is assumed to be a CommonJS Module that has been wrapped in an AMD wrapper. At execution time, these parameters are fulfilled with the three main CJS "free variables": require, exports, and module -- in this exact order. define(function (require, exports, module) { /* blah */ });
  2. a module can request these same variables as pseudo-dependencies by asking for them by name: define(["require"], function (require) { /* blah */ });

Using the local require:

In case 1, curl.js will scan the module for uses of require as an r-value (require with a single string param). It appends those modules to the dependency list, fetches them, and then executes the definition function. Therefore, any calls to require('myPkg/myModule') are simply lookups, no async fetching is needed since it happened before the definition function executed.

Case 2 is meant mostly for async fetching, but can be used for r-value functionality if you can guarantee that the module has already been fetched. The easiest way to do this is to place that module in the dependency list. Unless you're using a build tool that does this automatically, this is somewhat redundant.

Please note that the lookup rules for the module id in the r-value require() are the same as for the dependencies in the define(). You should probably use relative module ids for modules in the same folder or package. var sibling = require("./sibling");.

If you start sing the "exports" variable/pseudo-dep as well, there's a whole lot more to the story. I hope to have some docs up on the wiki soon after the 0.6 release.

Regards,

-- John

from curl.

unscriptable avatar unscriptable commented on August 24, 2024

Oops. Reopening the issue until 0.6 is released.

from curl.

tmaslen avatar tmaslen commented on August 24, 2024

Hi unscriptable,

Thanks for that. Now that I've plugged 0.6 into my app I can now do this...

define(['require', 'module/foo'], function(require) {
var foo = require('./foo');
return foo;
});

I think I've been attempting to do something that is not possible with an AMD loader. For example, I was hoping to do the following...

define(function() {
var history;
if ('history' in window) {
history = require('./nativeHistory');
}
else {
history = require('./polyfilledHistory');
}
return history;
});

Then only the module that was required would be downloaded. But this is not possible without the referenced modules being fetched already, as everything is async?

Regards,
/t

from curl.

unscriptable avatar unscriptable commented on August 24, 2024

Hey Tom,

You are right: using r-value require() isn't going to work in this case. However, it is certainly possible to dynamically load a module based upon feature detection. The easiest way is to use the async require(), but that won't work in your case since your code returns immediately. Plugins are necessary for this type of behavior. You have (at least) two choices:

  1. use the async! plugin.
  2. use the has! plugin

async! plugin:

The async! plugin was meant for this purpose, but is not very desirable since it forces you to specify "async!mylib/moduleId" all over the code rather than just "mylib/moduleId". I was just looking at that module and found a way to remove the need for the plugin syntax. This will likely be a 0.6.1 feature, but I can put something up in a branch for you to try out. I'll reopen this issue to track the progress of that new feature.

has! plugin:

A while back, a group of devs devised the has.js project. There has been some talk about building a has! plugin off of it. The dojo guys succeeded and are using it exhaustively in dojo 1.7.x. We've been toying with the idea. In fact, @briancavalier just did something very similar to what you proposed using the has! plugin last week. I don't know if the code is in a usable state, but I'll check with him to see if we can post a gist somewhere.

In either case, this use case should go onto the wiki.

-- John

from curl.

tmaslen avatar tmaslen commented on August 24, 2024

Thanks unscriptable. :-)

from curl.

unscriptable avatar unscriptable commented on August 24, 2024

Hey Tom,

I know this is a very old issue. Did you ever find a solution? I just realized we could do something like this:

// history.js
define([('history' in window) ? './nativeHistory' : './polyfilledHistory'], function(history) {
    return history;
});

AMD build tools won't bake-in either nativeHistory or polyfilledHistory. If you want to ensure one of them is baked-in, do this:

// history.js
// first dependency is ignored if it's falsey (but some AMD loaders may choke on this)
define([!('history' in window) && './polyfilledHistory', './nativeHistory'], function(polyfilled, native) {
    return polyfilled || native;
});

Please reopen if you're not satisfied with my answer :)

-- J

from curl.

tmaslen avatar tmaslen commented on August 24, 2024

Hey,

Yes this would work, that's obvious now :-)

We ended up wrapping every single AMD module into an all.js as it was so tiny (14kb) it was just easier that way.

But I'll definitely remember to use this technique if we need to conditionally load an AMD module.

You're awesome,
/t

from curl.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.