GithubHelp home page GithubHelp logo

Comments (13)

unscriptable avatar unscriptable commented on August 24, 2024

You've got a couple of options that might work for your projects already:

a) use protocol-relative or absolute paths

If your modules/resources are organized by type, then you can use the paths:

// config
curl({
    baseUrl: "http://this-is-ignored-by-the-paths-below.com/",
    paths: {
        "common/js": "//js.cdn.com/common/",
        "myApp/js": "//js.cdn.com/myApp1.3/",
        "myApp/css": "//css.cdn.com/myApp1.3/"
    }
});
// invoke:
curl(["js!myApp/js/jQuery1.6.3/jQuery", "link!myApp/css/core/screen.css"]);

b) use custom plugins

If your modules/resources are not organized by type, I could help you create custom plugin decorators that wrap the built-in plugins and translate the the host portion of the url.

These will be safe across upgrades since the API call we'll be overriding is locked-down by the AMD standard. And we'll just be extending curl's built-in plugins.

There isn't any documentation about decorating plugins, so let me know if you think this is the best solution for you and I'll help write them and show you how to bake them in.

from curl.

asilvas avatar asilvas commented on August 24, 2024

For some reason I had thought the plugin name (i.e. "js!") was used in the pathing "lookup". Unfortunately "a" isn't really an option for something already in place, and "modules" generally contain all of their resources unseperated by folders. Would seem a logical addition would be to allow "plugin!" in the paths -- that'd make a big difference. Sure could write custom plugins, but this is most certainly not isolated to just my needs, especially when "paths" already exists.

from curl.

unscriptable avatar unscriptable commented on August 24, 2024

Hm ok. The plain-old-javascript and css resources are already in place. Definitely a showstopper. :)

The possibility of "js!" and "css!" as properties of the paths config param came to mind. So far, that feels safe, but is stretching the semantics of paths imho.

There's also the possibility of adding baseUrl config options to the js! and css! plugins:

curl({
    plugins: {
        js: {
            baseUrl: "//js.cdn.com/"
        },
        css: {
            baseUrl: "//css.cdn.com/"
        }
    }
});

This makes a lot of sense to me. If you like it, we may have a solution. :)

You wrote:

"modules" generally contain all of their resources unseperated by folders

Can you elaborate? I'm confused by the word "modules" and "resources" in that sentence. Are you saying that all of your modules' dependencies live in the same folder as the module itself?

Can you show me a sample folder structure for some modules and resources? That might help me a lot.

-- J

from curl.

asilvas avatar asilvas commented on August 24, 2024

Can you elaborate? I'm confused by the word "modules" and "resources" in that sentence. Are you saying that all of your modules' dependencies live in the same folder as the module itself?

Yeah, just meant most modules have all their dependencies in the same folder, so breaking modules into multiple "root" folders would be an unnecessary complication (especially for a build system).

This makes a lot of sense to me. If you like it, we may have a solution. :)

Absolutely, that's a great solution. I only mentioned re-using "path" since it was already there, trying to save time & code bloat. But your solution is much better and would avoid potential conflicts.

from curl.

asilvas avatar asilvas commented on August 24, 2024

To clarify, the priority of pathing is: paths > plugins > baseUrl ? Not sure how else it could work without breaking things. If a path is provided, I assume it'd have to take priority over all others.

from curl.

unscriptable avatar unscriptable commented on August 24, 2024

To clarify, the priority of pathing is: paths > plugins > baseUrl ?

Yes. That seems right.

I've been contemplating one other potential feature that would also solve your pathing needs. It's one of those features that puts way too much rope in the hands of users, so I may keep it undocumented (but I'd be sure to add the proper tests if you decide to use it). Here it is:

curl({
    paths: {
        "module1": chooseCdn
    }
});

function chooseCdn (relativeUrl, absId) {
    // this function takes a relative url and a module id that has been normalized (no relative paths)
    // and returns a transformed url
    var base = absId.indexOf("js!") == 0 ? "//js.cdn.com/" : absId.indexOf("css!") == 0 ? "//css.cdn.com/" : '';
    return base + relativeUrl;
}

Of course, the sky's the limit once you have a function. :) And that is the reason I hesitate to document the feature. It's going to cause all sorts of confusion for noobs who haven't yet grokked how the paths and baseUrl work. As you know, confused noobs == major support burden.

Thoughts? Preferences?

from curl.

asilvas avatar asilvas commented on August 24, 2024

I'm not sure that would work, actually, as it requires the usage of paths to match against all cases. If you want to take that path (no pun intended), I'd simply add a "customPath" function to the root of the config. It'd work the same you described, though. Then you won't have to detect for functions on each path, either.

from curl.

unscriptable avatar unscriptable commented on August 24, 2024

I finally had a block of time to think this through. There are a couple of options, and yours ("js!", "css!", and "text!" paths) is pretty intriguing. There are pros and cons to both yours and mine.

In the end, yours won. Ultimately, yours fits a bit better with the AMD API and the desire to keep plugins as lightweight as possible. I also realized/remembered that baseUrl is a convenience feature, not a critical feature. The paths config object is the real deal.

Here's how it will look to you, the developer:

paths : {
    "modules": "path/to/modules/from/baseUrl",
    "js!jQuery": "//ajax.googleapis.com/ajax/libs/jquery/",
    "js!": "//js.cdn.com/"
},
plugins: {
    "js": { prefetch: false }
}

I assume you're not using google's cdn. I just wanted to show how specificity works. In the above example, a dependency of "js!jQuery/1.6.3/jQuery" will resolve to "//ajax.googleapis.com/ajax/libs/jquery/1.6.3/jQuery.js". A dependency of any other js! resource will use "//js.cdn.com/", e.g. "js!megatron.js" --> "//js.cdn.com/megatron.js".

I added the plugins config object in my example to illustrate that the plugins get their config properties via a dedicated plugins object. My desire for consistency and organization drove me to the solution I had proposed. Since plugins rely on the loader to resolve urls, this solution would have been more effort. It would also have decentralized the paths, which wouldn't be as simple to the developer.

I am coding it now. Will have something testable shortly if all goes well. :)

from curl.

asilvas avatar asilvas commented on August 24, 2024

This is looking good.

A couple things aren't clear to me though:

  • Will all "js!" resources goto the CDN (in your example) unless a specific path override (like your 2nd path example) regardless of what the path is? In other words, if an absolute path is provided ("js!/sameapp/myfile.js" for same domain, or "js!//myothercdn/myfile.js"). I have a bad feeling the examples I gave will no longer work after the change. There are ways to work around the issue (such as using "js!root" for unique naming), but I can certainly see accidental breaks unless plugin matches do not account for absolute paths ("/path" or "//domain/path" or "http(s)://domain/path") and not match against those. The golden rule being, paths should be ignored whenever an absolute uri is passed in. It may already do this, but want to make sure.
  • What is the purpose of the "prefetch: false" option? Any other plugin options?

from curl.

unscriptable avatar unscriptable commented on August 24, 2024

Initial tests look good! I need to create some real test cases before committing, though.

The golden rule being, paths should be ignored whenever an absolute uri is passed in. It may already do this, but want to make sure.

Yep. I agree. Need to test it. :)

What is the purpose of the "prefetch: false" option? Any other plugin options?

The soon-to-be-renamed prefetch option (it is currently called "jsPrefetch") instructs the js! plugin whether it should attempt to prefetch the javascript file using the type="text/cache" mime type. The default is true. When using this mime type, browsers (except FF3.6) will fetch the script, but not execute it. A second fetch using type="text/javascript" will grab the file from the cache and execute it.

This is useful if you're ordering the scripts and want to download them all in parallel. For this trick to work, the browser must cache the file, of course. You must have the proper http headers or the browser won't cache. If you can't guarantee that the browser will cache the files, you could set prefetch: false to prevent the file from potentially downloading twice.

Actually, this prefetch technique is only used if one of the other options (!noexec and !order) is specified. The other options are only available as suffixes to the resource id, e.g. curl(["js!jQuery.js!order", "js!jQueryUI.js!order"]).

!order forces js files to be executed in order. If prefetch is true, they'll still download in parallel as described above.

!noexec appears to be broken at the moment -- or my test is. It's purpose is to load, but not execute the javascript. This could come in handy if you wanted to just get the file into the cache for fast loading later.

If you're nervous some dev may use the !order suffix in an uncacheable situation, then it's safest to set prefetch: false I guess.

from curl.

asilvas avatar asilvas commented on August 24, 2024

I see, so you're using the "plugins" object to specify defaults specific to that plugin. Sounds good, with plenty of future potential for its usage.

Do you have any special handling for browsers which do not support "text/cache" mime type? Not a concern, just curious.

from curl.

unscriptable avatar unscriptable commented on August 24, 2024

The "text/cache" mime type is the fallback for browsers that don't yet support async="false". There are other ways to get a script into the cache, but they all have their setbacks. Using new Image("script/source.js"); works great except in Chrome, which has the "sticky mime types" issue. document.createElement('object'); works in almost all, afaik.

"text/cache" seems the best since it's been proposed as a standard to the w3c (and thankfully voted down, iirc) and browser vendors seem to be aware of its use.

from curl.

unscriptable avatar unscriptable commented on August 24, 2024

fixed on dev branch. Still one more issue before I merge to trunk.

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.