{"id":13447107,"url":"https://github.com/cujojs/curl","last_synced_at":"2025-10-04T11:07:39.972Z","repository":{"id":58219744,"uuid":"1314976","full_name":"cujojs/curl","owner":"cujojs","description":"curl.js is small, fast, extensible module loader that handles AMD, CommonJS Modules/1.1, CSS, HTML/text, and legacy scripts.","archived":false,"fork":false,"pushed_at":"2019-05-04T01:15:14.000Z","size":4231,"stargazers_count":1876,"open_issues_count":42,"forks_count":207,"subscribers_count":98,"default_branch":"master","last_synced_at":"2025-09-01T11:02:05.482Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://github.com/cujojs/curl/wiki","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/cujojs.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2011-02-01T04:07:47.000Z","updated_at":"2025-08-10T18:31:47.000Z","dependencies_parsed_at":"2022-08-31T02:50:49.466Z","dependency_job_id":null,"html_url":"https://github.com/cujojs/curl","commit_stats":null,"previous_names":[],"tags_count":38,"template":false,"template_full_name":null,"purl":"pkg:github/cujojs/curl","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cujojs%2Fcurl","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cujojs%2Fcurl/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cujojs%2Fcurl/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cujojs%2Fcurl/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cujojs","download_url":"https://codeload.github.com/cujojs/curl/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cujojs%2Fcurl/sbom","scorecard":{"id":312532,"data":{"date":"2025-08-11","repo":{"name":"github.com/cujojs/curl","commit":"13170edcbeb9dc55c48ea00e5fec890eec75b59f"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3.3,"checks":[{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Code-Review","score":2,"reason":"Found 6/28 approved changesets -- score normalized to 2","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"License","score":9,"reason":"license file detected","details":["Info: project has a license file: LICENSE.txt:0","Warn: project license file does not contain an FSF or OSI license."],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 9 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}}]},"last_synced_at":"2025-08-17T23:26:22.011Z","repository_id":58219744,"created_at":"2025-08-17T23:26:22.012Z","updated_at":"2025-08-17T23:26:22.012Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":278302555,"owners_count":25964523,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-04T02:00:05.491Z","response_time":63,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-07-31T05:01:08.396Z","updated_at":"2025-10-04T11:07:39.950Z","avatar_url":"https://github.com/cujojs.png","language":"JavaScript","readme":"curl (cujoJS resource loader)\n=====================\n\nAll development for curl.js and cram.js has stopped. For the foreseeable future, we will continue to respond to issues on github, as well as in the #cujojs room on freenode.  However, keep in mind that there will be no further development, so some issues might not be resolved fully.\n\nAlso, if you are interested in becoming the lead maintainer of curl.js and/or cram.js, please let us know on #cujojs!\n\nWhat is curl.js?\n================\n\ncurl.js is a small and very fast AMD-compliant asynchronous loader.\nSize: ~4KB (gzipped) using Google's Closure Compiler.\n\nIf you'd like to use curl.js for non-AMD modules (ordinary javascript files),\nyou'll want to use the legacy loader.\n\ncurl.js, like all async loaders, cannot circumvent browsers' security\nrestrictions when using the `file:` protocol.  Therefore, you must use\ncurl from a page served from a web server (i.e. using `http:` or `https:`).\nTrying to run curl.js from a page loaded from your local file system\nwill not work correctly in all browsers.\n\nWhat the heck is \"cujoJS\"?  cujoJS is the JavaScript Architectural Toolkit.\nMore info: [cujojs.com](http://cujojs.com)\n\nWhat is \"cram\"? cram (cujoJS resource assembler) is the build tool companion to\ncurl.js.  You use cram to compile all of your modules into a small number of\njavascript files which are loaded much faster into the browsers.\n\n----------------------------------------\n\nFeatures at a glance:\n=====================\n\n* Loads AMD-formatted javascript modules in parallel\n* Loads CommonJS/node modules (v1.1 when wrapped in a `define()`)\n* Loads CommonJS/node modules (unwrapped when using the cjsm11 loader)\n* Loads non-AMD javascript files in parallel, too.\n* Loads CSS files and text files in parallel\n* Waits for dependencies (js, css, text, etc) before executing javascript\n* Waits for domReady, if desired\n* Allows for virtually limitless combinations of files and dependencies\n* Tested with Safari 5+, IE6+, and recent Chrome, FF, Opera\n\nMore detailed information below and on the\n[wiki](https://github.com/cujojs/curl/wiki).\n\n----------------------------------------\n\nHow to get support\n===============\n\n1. Go to the issues section of the curl repo\n   (https://github.com/cujojs/curl/issues) and search for an answer to your\n   question or problem.\n2. If no answer exists, file a new ticket!  Somebody will typically respond\n   within a few hours.\n\nIt's that easy.\n\nGot more in-depth questions?  Browse the\n[cujoJS discussion group](https://groups.google.com/d/forum/cujojs) or\ncome chat with us on freenode @ #cujojs.\n\nSee the [wiki](https://github.com/cujojs/curl/wiki) for information about using\ncurl.js with jQuery, dojo, or underscore.\n\n----------------------------------------\n\nWhat's New?\n=======\n\n* 0.8.12\n    * Add deprecation notice.\n    * Add links to Rave Starters.\n    * Add a link to the migration guide.\n* 0.8.11\n    * Improve instructions for custom build thanks to @azazel75.\n    * Stop catching (and indirectly squelching) errors in callback functions. Fixes #281.\n    * Add version number at the beginning. Thanks @szepeviktor!\n    * Add note about config options that are not supported in embedded config.\n    * Added img! plugin and test cases.  Thanks @asilvas!\n    * Recognize Windows absolute urls. C:\\, e:/, etc. Thanks @doom777!\n    * Update to README.md to correct link to James Burke's site.  Thanks @kryger!\n* 0.8.10\n\t* Add moduleType and main properties to bower.json and package.json.\n* 0.8.9\n\t* Protect more API functions in plugins and loaders from closure compiler's\n\taggressive obfuscation.\n\t* Switch to newer //# sourceURL syntax.\n\t* Stop doubling the \".js\" on the sourceURL.\n\t* Ensure that `define` is undefined when wrapping cjs/node modules.\n* 0.8.8\n\t* Stop double-appending .css extension in css! plugin.\n\t(thanks @stanislawosinski!)\n* 0.8.7\n\t* Fix botched release wherein some dummy forgot to `bin/make-all.sh`.\n* 0.8.6\n\t* Cram plugins: hide legacy plugin's `define` from cram parser.\n* 0.8.5\n\t* Cram plugins: plugins are now responsible for resolving url/filepath.\n\t* Cram plugins: legacy loader no longer fails to add a .js extension\n\t  when there are dots in the file name.\n\n----------------------------------------\n\nAPI at a glance\n===============\n\nAt it's core, curl.js provides an AMD environment:\n\n```javascript\ndefine(['dep1', 'dep2', 'dep3' /* etc */], factory);\ndefine(['dep1', 'dep2', 'dep3' /* etc */], module);\ndefine(module);\ndefine(name, ['dep1', 'dep2', 'dep3' /* etc */], factory);\ndefine(name, ['dep1', 'dep2', 'dep3' /* etc */], module);\ndefine(name, module);\n```\n\nThese all define a module per the AMD specification.\n\n* ['dep1', 'dep2', 'dep3']: Module names or plugin-prefixed resource files.\nDependencies may be named 'require', 'exports', or 'module' and will behave\nas defined in the CommonJS Modules 1.1 proposal.\n* factory: Function called to define the module.  Each dependency is\n  passed as a parameter to the factory.\n* module: Any javascript object, function, constructor, or primitive\n* name: String used to name a module. This is not necessary nor is it\n  recommended.  \"Named modules\" are typically only created by build tools\n  and AMD bundlers.\n\n----------------------------------------\n\n```javascript\ndefine(function (require, exports, module) {\n\tvar dep1 = require('app/foo');\n\texports.foo2 = function () { return foo() + 2; };\n});\n```\n\nDefines a module using the AMD-wrapped-CommonJS format.  If a factory function\nhas parameters, but the dependency list is missing, this format is assumed.\nThe `exports` and `module` parameters are optional, but when specified, must\nbe in this exact order.\n\n----------------------------------------\n\n```javascript\ndefine(function (require) {\n\tvar dep1 = require('app/foo');\n\treturn function () { return foo() + 2; };\n});\n```\n\nAnother variation on AMD-wrapped-CommonJS that uses `require()` in the\ntidy CommonJS manner, but returns the exports as per typical AMD.\n\n----------------------------------------\n\n```javascript\ndefine(['require', 'exports', 'module'], function (require, exports, module) {\n\tvar dep1 = require('app/foo');\n\texports.foo2 = function () { return foo() + 2; };\n});\n```\n\nAnother way to gain access to the CommonJS-like variables, `require`,\n`exports`, `module`.  When specified in the dependency list, these\n\"pseudo-modules\" are provided as arguments to the factory function.\n\n----------------------------------------\n\n```javascript\nvar dep1 = require('app/foo');\nexports.foo2 = function () { return foo() + 2; };\n```\n\ncurl.js also supports *unwrapped* CommonJS modules (and node.js modules)\nvia the cjsm11 module loader. To use this module loader for a package, say\nBackbone, you would provide it to a package config, like this:\n\n```javascript\ncurl.config({\n\tpackages: [\n\t\t{\n\t\t\tname: 'backbone',\n\t\t\tlocation: 'bower_components/backbone',\n\t\t\tmain: 'backbone.min.js',\n\t\t\tconfig: { moduleLoader: 'curl/loader/cjsm11' } /* \u003c-- hey! */\n\t\t}\n\t]\n});\n```\n\nRead the notes in the src/curl/loader folder and the cjsm11.js file for\nmore information about loading CommonJS and node.js modules.\n\n-----\n\ncurl.js's global API is for bootstrapping an app.  You would typically only use\nthis API *once* in your application to load the main module of your application.\n\nFor a complete description, check out the [wiki](https://github.com/cujojs/curl/wiki).\n\n```javascript\ncurl(['main', 'other', 'another' /* etc */], callback, errorback);\n```\n\nLoads a module named \"main\" along with two other modules and then executes\ncallback, handing it the exported values of the modules as parameters.\n\n* ['main', 'other', 'another']: Module names or plugin-prefixed resource files.\n* callback: Function to receive modules or resources. This is where you'd\n  typically start up your app. Optional.\n* errorback: Function to receive an exception parameter when loading fails.\n   Optional.\n\n---------\n\n```javascript\ncurl(['main', 'other', 'another' /* etc */])\n\t.then(callback, errorback);\n```\n\nPromises-based API for executing callbacks.\n\n* ['main', 'other', 'another']: Module names or plugin-prefixed resource files.\n* callback: Function to receive modules or resources. Optional.\n* errorback: Function to call if an exception occurred while loading. Optional.\n* Note: curl.js's Promises are *not* compliant with ES6 or Promises/A+ so they may not behave as you'd expect. For full compliance, use [when.js](https://github.com/cujojs/when) or any another ES6 Promise shim.\n    * `when(curl(['dep1'])).then(callback);` or `Promise.resolve(curl(['dep1'])).then(callback);`\n\n---------\n\n```javascript\ncurl(config, ['main' /* etc */], callback, errorback);\n```\nSpecify configuration options, load dependencies, and execute callback.\n\n* config: Object containing curl configuration options (paths, etc.)\n* ['main']: Module name(s).\n* callback: Function to receive modules or resources. Optional.\n* errorback: Function to call if an exception occurred while loading. Optional.\n\n---------\n\n```javascript\ncurl(['main', 'domReady!' /* etc */]).then(\n\tcallback,\n\terrorback\n);\n```\n\n```javascript\ncurl(['main', 'domReady!' /* etc */], function (main) {\n\t// do some bootstrapping here\n});\n```\n\nExecutes the callback when the dom is ready for manipulation AND\nall dependencies have loaded.\n\n---------\n\n```javascript\ncurl(['domReady!', 'js!nonAMD.js!order', 'js!another.js!order']), function () {\n\t/* do something cool here */\n});\n```\n\nExecutes the function when the non-AMD javascript files are loaded and\nthe dom is ready. The another.js file will wait for the nonAMD.js file\nbefore executing.\n\nNote: Please use curl.js's new legacy loader for much more flexible and\nsensible loading of non-AMD scripts.  Please read the docs in the\nsrc/curl/loader folder for more information.\n\nNote: if a file supports AMD or CommonJS module formats, you *can not* use the\njs! plugin on that file.\n\n---------\n\n```javascript\ncurl(['js!nonAMD.js'])\n\t.next(['dep1', 'dep2', 'dep3'], function (dep1, dep2, dep3) {\n\t\t// do something before the dom is ready\n\t})\n\t.next(['domReady!'])\n\t.then(\n\t\tfunction () {\n\t\t\t// do something after the dom is ready\n\t\t},\n\t\tfunction (ex) {\n\t\t\t// show an error to the user\n\t\t}\n\t);\n```\n\nExecutes callbacks in stages using `.next(deps, callback)`.\n\nNote: `.next()` does not load resources in parallel.  Therefore, it is a\nlast resort when other options do not satisfy your use case.  You should\nuse the `preloads` config option and/or the legacy loader\nwhenever possible.\n\n---------\n\n```javascript\ncurl = {\n\tbaseUrl: '/path/to/my/js',\n\tpluginPath: 'for/some/reason/plugins/r/here',\n\tpaths: {\n\t\tcurl: 'curl/src/curl',\n\t\tcssx: 'cssx/src/cssx',\n\t\tmy: '../../my-lib/'\n\t},\n\tapiName: 'someOtherName'\n};\n```\n\nIf called before the `\u003cscript\u003e` that loads curl.js, a global `curl` var will\nconfigure curl.js when it loads.  All of the configuration parameters are\noptional. curl.js tries to do something sensible in their absence. :)\n\nSome common configuration options:\n\n* baseUrl: the root folder to find all modules, default is the document's folder\n* paths: a mapping of module paths to relative paths (from baseUrl)\n* pluginPath: the place to find plugins when they are specified without a path\n(e.g. \"css!myCssFile\" vs. \"cssx/css!myCssFile\") and there is no paths\nmapping that applies.\n* apiName: an alternate name to `curl` and `require` for curl.js's global\n  variable\n* apiContext: an object, rather than `window`, to place curl on when using\n  `apiName`\n\nA more complete list can be found on the\n[wiki](https://github.com/cujojs/curl/wiki/Configuring-curl.js).\n\n----------------------------------------\n\nVery Simple Example\n===================\n\n```html\n\u003cscript\u003e\n\n\t// configure curl\n\tcurl = {\n\t\tpaths: {\n\t\t\tcssx: 'cssx/src/cssx/',\n\t\t\tstuff: 'my/stuff/'\n\t\t}\n\t};\n\n\u003c/script\u003e\n\u003cscript src=\"../js/curl.js\" type=\"text/javascript\"\u003e\u003c/script\u003e\n\u003cscript type=\"text/javascript\"\u003e\n\n\tcurl(\n\t\t// fetch all of these resources (\"dependencies\")\n\t\t[\n\t\t\t'stuff/three', // an AMD module\n\t\t\t'cssx/css!stuff/base', // a css file\n\t\t\t'i18n!stuff/nls/strings', // a translation file\n\t\t\t'text!stuff/template.html', // an html template\n\t\t\t'domReady!'\n\t\t]\n\t)\n\t// when they are loaded\n\t.then(\n\t\t// execute this callback, passing all dependencies as params\n\t\tfunction (three, link, strings, template) {\n\t\t\tvar body = document.body;\n\t\t\tif (body) {\n\t\t\t\tbody.appendChild(document.createTextNode('three == ' + three.toString() + ' '));\n\t\t\t\tbody.appendChild(document.createElement('br'));\n\t\t\t\tbody.appendChild(document.createTextNode(strings.hello));\n\t\t\t\tbody.appendChild(document.createElement('div')).innerHTML = template;\n\t\t\t}\n\t\t},\n\t\t// execute this callback if there was a problem\n\t\tfunction (ex) {\n\t\t\tvar msg = 'OH SNAP: ' + ex.message;\n\t\t\talert(msg);\n\t\t}\n\t);\n\n\u003c/script\u003e\n```\n\nThe file structure for this example would look as follows:\n\n\tjs/\n\t\tcurl/\n\t\t\tplugin/\n\t\t\t\ti18n.js\n\t\t\t\ttext.js\n\t\t\tdomReady.js\n\t\tcssx/\n\t\t\tsrc/\n\t\t\t\tcssx/\n\t\t\t\t\tcss.js\n\t\tmy/\n\t\t\tstuff/\n\t\t\t\tnls/\n\t\t\t\t\tstrings.js\n\t\t\t\tbase.css\n\t\t\t\ttemplate.html\n\t\t\t\tthree.js\n\t\tcurl.js\n\n----------------------------------------\n\nWhat is an asynchronous loader?\n===============================\n\nWeb apps, especially large ones, require many modules and resources. Most of\nthese modules and resources need to be loaded at page load, but some may be\nloaded later, either in the background or \"just in time\". They also need to be\nloaded as quickly as possible.\n\nThe traditional way to load javascript modules is via a `\u003cSCRIPT\u003e` element in\nan HTML page. Similarly, CSS files are loaded via a `\u003cLINK\u003e` element, and\ntext resources are either loaded in the page or via XHR calls.\n\nThe problem with `\u003cSCRIPT\u003e` and `\u003cLINK\u003e` elements is that a browser must execute\nthem sequentially since it has no idea if one may depend on another. It just\nassumes the developer has placed them in the correct order and that there are\ndependencies. (The term \"synchronous loading\" is used to describe this process\nsince the elements are executed in a single timeline.)\n\nIf there are no dependencies between two files, loading them sequentially is\na waste of time. These files could be loaded and executed in parallel (i.e\nat the same time).\n\nAn asynchronous loader does just that: it loads javascript files (and\nother types of files) in parallel whenever possible.\n\ncurl.js has lots of company. Other async loaders include LABjs, Steal.js,\nyepnope.js, $script.js, the Backdraft loader (bdLoad), and RequireJS.\n\n[(a more complete list)](https://spreadsheets.google.com/ccc?key=0Aqln2akPWiMIdERkY3J2OXdOUVJDTkNSQ2ZsV3hoWVE\u0026hl=en#gid=2)\n\n----------------------------------------\n\nWhat is AMD?\n============\n\nAsynchronous Module Definition is a *de facto* standard for\njavascript modules that can be loaded by asynchronous loaders. It defines\na simple API that developers can use to write their javascript modules so\nthat they may be loaded by any AMD-compliant loader.\n\n[AMD Spec](https://github.com/amdjs/amdjs-api/wiki/AMD)\n\nThe AMD proposal follows some parts of the\n[CommonJS Modules](http://wiki.commonjs.org/wiki/Modules/1.1) proposal.\nBecause of the way browsers load and\nevaluate scripts, AMD can't follow it completely without causing significant\nprocessing overhead.  Instead, AMD allows us to place a lightweight wrapper\naround javascript modules to help work around the shortcomings.\n\nUltimately, both proposals (AMD and Modules 1.1) are in preparation for an\nofficial [javascript modules](http://wiki.ecmascript.org/doku.php?id=harmony:modules)\nspecification and eventual implementation in browsers.\n\nIf you don't want to wait for official javascript modules, then don't.\nThe future is now.  AMD works now -- and it's awesome.\n\nAMD's API focuses on one globally-available function: `define()` and some\nCommonJS-inspired variables, `require()`, `exports`, and `module`.\n`require()` specifies a list of dependent modules or resources that must be\nloaded before running a set of code. This code resides in a callback function\nthat is executed asynchronously, i.e. it runs later, not in the current\n\"thread\".  Specifically, it executes when all of the dependencies are loaded\nand ready.\n\nThe proposal does not mandate that `require()` be specified globally.  In fact,\nat a global level, the concerns of a loader are about application bootstrapping\nand not about finding dependencies. To keep the confusion about these two\nconcepts to a minimum, curl.js uses `curl()` for the public API.  You may rename\nthis API back to `require()` by supplying the `apiName` config param\n(`apiName: \"require\"`), but this is not recommended.\n\nIt's more important that the `define()` method be consistent.  This is the\nmethod that tells the loader what modules have been loaded by a script.\n`define()`  also specifies a list of dependencies and a callback function that\ndefines and/or creates the resource when the dependencies are ready.\nOptionally, `define()` also takes a name parameter, but this is mainly for build\ntools and optimizers.\n\nInside the `define()`, the `require()` method acts like other AMD loaders.\n\nAMD's API also helps code reuse by providing compatibility with CommonJS\n(server) modules. AMD-compliant loaders support the same `require()` syntax and\nargument signatures as server-side javascript (ssjs) modules.\n\nThe beauty of AMD loaders is their ability to remove the drudgery of manually\nmanaging dependencies.  Since all dependencies are listed within the\nmodules, the loader will ensure that everything is loaded into the browser --\nand in the right order.\n\n----------------------------------------\n\nCan curl.js work with non-AMD and non-CommonJS javascript files?\n===============================================\n\nYes, but why would you?  Once you start using AMD, you'll never go back! :)\n\nYou may use non-AMD javascript files by using the legacy loader\nlike this:\n\n```javascript\ncurl.config({\n\tpaths: {\n\t\tplainOldJsFile1: {\n\t\t\tlocation: 'js/plainOldJsFile1.js',\n\t\t\tconfig: { loader: 'curl/loader/legacy', exports: 'aGlobal' }\n\t\t},\n\t\tanotherPlainOldJsFile: {\n\t\t\tlocation: 'js/anotherPlainOldJsFile.js',\n\t\t\tconfig: {\n\t\t\t\tloader: 'curl/loader/legacy',\n\t\t\t\texports: 'anotherGlobal',\n\t\t\t\trequires: [ 'plainOldJsFile1' ]\n\t\t\t}\n\t\t}\n\t}\n});\ncurl(['anotherPlainOldJsFile']).then(\n\tfunction (anotherGlobal) {\n\t\t/* do something with your plain, boring javascript files */\n\t},\n\tfunction () {\n\t\t/* do something if any fail to load */\n\t}\n);\n```\n\nPlease read the docs in the src/curl/loader folder for more information.\n\n----------------------------------------\n\nCan curl.js load non-javascript files via plugins?\n=======================\n\nYes, curl.js follows the CommonJS Loader Plugin specification, so you can use\nany compatible plugin. The following plugins are included:\n\njs! -- loads non-AMD javascript files. more info on the [wiki](https://github.com/cujojs/curl/wiki/js)\n\ntext! -- loads text files\n\nlink! -- loads css files via a link element (simple, fast)\n\ncss! -- loads css files (lots of options)\n\ndomReady! -- resolves when the dom is ready for manipulation\n\nasync! -- resolves when a module signals it's ready\n\ni18n! -- loads text strings and other locale-specific constants\n\nSome plugin docs are on the [wiki](https://github.com/cujojs/curl/wiki/Plugins).\n\nMore documentation is available inside the source of these plugins!\n\n----------------------------------------\n\nHow are modules loaded?\n=======================\n\ncurl.js uses `\u003cscript\u003e` element injection rather than XHR/eval for AMD modules.\nThis allows curl.js to load cross-domain scripts as well as local scripts.\nCommonJS modules use XHR/eval so must be wrapped for \"transport\" if not\non the same domain.  Typically, you will bundle your modules before using them\nin production, anyways.  Most bundlers will wrap CommonJS modules in AMD.\n\nTo find scripts and other resources, curl.js uses module names.  A module name\nlooks just like a file path, but typically without the file extension.  If a\nmodule requires a plugin in order to load correctly, it will have a prefix\ndelimited by a \"!\" and will also often have a file extension when a plugin\nmay load different types of files.\n\nSome examples of module names:\n\n* dojo/store/JsonRest\n* my/lib/string/format\n* js!my/lib/js/plain-old-js.js\n* css!my/styles/reset.css\n* http://some-cdn/uber/module\n\nBy default, curl.js will look in the same folder as the current document's\nlocation. For instance, if your web page is located at\n`http://my-domain/apps/myApp.html`, curl.js will look for the JsonRest module\nat `http://my-domain/apps/dojo/store/JsonRest.js`.\n\nYou can tell curl.js to find modules in other locations by specifying a baseUrl\nor individual packages for each of your libraries.  For example, if you specify\na baseUrl of `/resources/` and the following paths:\n\n```javascript\npackages: [\n\t{ name: \"dojo\", location: \"third-party/dojo\" },\n\t{ name: \"css\", location: \"third-party/cssmojo/css\" },\n\t{ name: \"my\", location: \"my-cool-app-v1.3\" },\n\t{ name: \"my/lib/js\", location: \"old-js-libs\" }\n]\n```\n\nThen the modules listed above will be sought in the following locations:\n\n* /resources/third-party/dojo/store/JsonRest.js\n* /resources/my-cool-app-v1.3/lib/string/format.js\n* /resources/old-js-libs/plain-old-js.js\n* /resources/my-cool-app-v1.3/styles/reset.css\n* http://some-cdn/uber/module.js\n\nNote: you will need to create a path to curl.js's plugins and other modules if\nthe curl folder isn't directly under the same folder as your web page. curl.js\nuses the same mechanism to find its own modules.\n\n----------------------------------------\n\nWhat are AMD plugins?\n=====================\n\nAMD supports the notion of plugins. Plugins are AMD modules that can be used to\nload javascript modules -- or other types of resources. curl comes with several\nplugins already, including a text plugin (for templates or other text\nresources), two different css plugins, a dom-ready plugin, and several others.\n\nPlugins are designated by a prefix on the name of the module or resource to be\nloaded. They are delineated by a ! symbol. The following example shows the use\nof some plugins:\n\n```javascript\ndefine(\n\t[\n\t\t'text!myTemplate.html',\n\t\t'css!myCssFile'\n\t],\n\tfunction (templateString, cssLinkNode) {\n\t\t// do something with the template and css here\n\t}\n);\n```\n\nSince plugins are just AMD modules, they would typically be referenced using\ntheir fully-pathed names. curl provides a pluginPath configuration option that\nallows you to specify the folder where [most of] your plugins reside so you\ndon't have to specify their full paths.  This also helps with compatibility\nwith other AMD loaders.\n\nIf one or more of your plugins does not reside in the folder specified by the\npluginPath config option, you can use its full path or you can specify a path\nfor it in curl's `paths` config object.\n\n```javascript\n// example of a fully-pathed plugin under the lib/cssx folder\ndefine(['lib/cssx!myCssFile'], function (cssxDef) {\n\t// do some awesome css stuff here\n});\n```\n\nPlugins can also have configuration options. Global options can be specified\non curl's configuration object. Options can also be supplied to plugins via\nsuffixes. Suffixes are also delineated by the ! symbol. Here's an example of\na plugin using options:\n\n```javascript\n// don't try to repair IE6-8 opacity issues in my css file\ndefine(['css!myCssFile!ignore:opacity'], function (cssxDef) {\n\t// do some awesome css stuff here\n});\n```\n\n----------------------------------------\n\nHow do I use curl.js?\n=====================\n\n1. Learn about AMD-formatted javascript modules if you don't already know how.\n2. Clone or download curl to your local machine or server.\n3. Figure out the baseUrl and paths configuration that makes sense for your\n   project.\n4. Check out the \"API at a glance\" section above to figure out which loading\n   methodology you want to use.\n5. Study the \"Very Simple Example\" and some of the test files.\n6. Try it on your own files.\n\n----------------------------------------\n\nToo Many Modules!\n=================\n\nI have dozens (or hundreds) of modules. Even with parallel loading, the\nperformance sucks! What can I do about that?\n\nTrue! No parallel loader can lessen the latency required to create an HTTP\nconnection. If you have dozens or hundreds of files to download, it's going to\ntake time to initiate each of the connections.\n\nHowever, there are tools to that are designed to fix this problem! There are\nbuilders and compilers. dojo users are probably already familiar with dojo's\nbuild tool and optimizer. RequireJS comes with a build tool and Google's\nClosure compiler.\n\nThe build tool is used to concatenate several modules (and/or resources)\ninto just a few files. It does this by following the dependency chain\nspecified in the define() and require() calls. You can specify which top-level\nmodules or resources are in each file and the build tool finds the rest.\n\nAfter the build tool creates the concatenated files, the files can be passed\ninto a compiler (also called a shrinker or compressor).\n\ncurl.js is compatible with RequireJS's build tool, r.js, but there's\nalso [cram](https://github.com/cujojs/cram).\nCram is the cujoJS resource assembler.\n\n----------------------------------------\n\nPackage Support\n========================\n\ncujoJS supports packages.  Packages are defined by the `packages`\nconfiguration parameter:\n\n```javascript\ncurl = {\n\tbaseUrl: 'path/to/js',\n\tpackages: {\n\t\t'my-package': {\n\t\t\tlocation: 'path/to/my-package',\n\t\t\tmain: 'main/main-module-file',\n\t\t\tconfig: { /* package-specific configuration options */ }\n\t\t}\n\t}\n};\n```\n\n```javascript\ncurl = {\n\tbaseUrl: 'path/to/js',\n\tpackages: [\n\t\t{\n\t\t\tname: 'my-package',\n\t\t\tlocation: 'path/to/my-package',\n\t\t\tmain: 'main/main-module-file',\n\t\t\tconfig: { /* package-specific configuration options */ }\n\t\t}\n\t]\n};\n```\n\nThe path property describes where to find the package in relation to the\nbaseUrl parameter.  The main and lib properties describe where to find modules\ninside the package.  The main property gives the relative path to the package's\nmain module.\n\nIn the example above, the main module of the package can be obtained as follows:\n\n```javascript\ncurl(['my-package'], callback);\n```\n\nand will be fetched from the following path:\n\n\tpath/to/js/path/to/my-package/main/main-module-file.js\n\nSome other file in the package would be obtained as follows:\n\n```javascript\ncurl(['my-package/other-module'], callback);\n```\n\nand will be fetched from the following path:\n\n\tpath/to/js/path/to/my-package/other-module.js\n\nNote that a package may also contain it's own embedded set of `config` options.  Most, but not all, config options may be specified here.  Specifically, you cannot specify any options that change the path or id of modules, such as `paths`, `packages`, `plugins`, or `'pluginPrefix`.\n\n----------------------------------------\n\nWhat is cujoJS?\n=====================\n\ncujoJS is the JavaScript Architectural Toolkit.  It employs MVC, IOC, AMD\nand lots of other TLAs. :)  Our goal is to provide architectural tools and\nguidance.  Find out more at [cujoJS.com](http://cujojs.com).\n\nKudos\n=================\n\nMany thanks to Bryan Forbes ([@bryanforbes](http://www.twitter.com/bryanforbes))\nfor helping to clean up my code and for making curl's domReady much more robust\nand help with dojo compatibility.\nMore about Bryan: \u003chttp://www.reigndropsfall.net/\u003e\n\nKudos also to James Burke ([@jrburke](http://www.twitter.com/jrburke)) who\ninstigated the AMD standard and paved the way to create AMD-style loaders.\nMore about James: \u003chttp://jrburke.com/about/\u003e\n\nShout out to Kris Zyp ([@kriszyp](http://www.twitter.com/kriszyp)) for\nexcellent ideas and feedback and to Kyle Simpson\n([@getify](http://www.twitter.com/getify)) who is inarguably the godfather of\njavascript loading.\n","funding_links":[],"categories":["JavaScript","Loaders","Loaders [🔝](#readme)","加载器"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcujojs%2Fcurl","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcujojs%2Fcurl","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcujojs%2Fcurl/lists"}