是否存在任何用于浏览器内javascript的库,它们提供与Node require
相同的灵活性/模块性/易用性?
提供更多详细信息:require
非常好的原因是:
jQuery.ajax()
var dsp = require("dsp.js");
加载,我可以访问dsp.FFT
,这不会干扰我的本地{{1} } 我还没有找到一个能够有效完成这项工作的库。我倾向于使用的解决方法是:
coffeescript-concat - 很容易需要其他js,但你必须编译它,这意味着它不太适合快速开发(例如构建API in-test)
< / LI> RequireJS - 它很受欢迎,直截了当,并解决了1-3,但缺少范围确定是一个真正的交易破坏者(我相信head.js是相似的,因为它缺乏范围,虽然我从来没有机会使用它。同样,LABjs可以加载,var FFT
可以缓解依赖性问题,但它仍然没有确定范围。
据我所知,似乎有很多动态和/或异步加载javascript的解决方案,但它们往往具有与从HTML加载js相同的范围问题。最重要的是,我想要一种加载不会污染全局命名空间的javascript的方法,但仍允许我加载和使用库(就像节点的要求一样)。
编辑(我的答案):自写这篇文章以来,我已广泛使用RequireJS(现在有更清晰的文档)。在我看来,RequireJS确实是正确的选择。我想澄清一下这个系统如何适用于那些和我一样困惑的人:
您可以在日常开发中使用.wait()
。模块可以是函数返回的任何内容(通常是对象或函数),并且作为参数确定范围。您还可以使用require
将项目编译为单个文件以进行部署(实际上,这几乎总是更快,即使{{1}}可以并行加载脚本)。
RequireJS和node-style之间的主要区别就像browserify(由tjameson建议的一个很酷的项目)使用的是模块的设计和要求:
r.js
获取要加载的模块(javascript文件)列表和回调函数。当它加载了每个模块时,它会调用每个模块的回调作为回调的参数。因此,它是真正的异步,因此非常适合网络。require
是一个阻塞调用,它加载模块并将其作为对象返回。这适用于Node,因为文件从文件系统读取,这足够快,但在Web上工作不佳,因为同步加载文件可能需要更长的时间。在实践中,许多开发人员在看到AMD之前就使用过Node(因此也使用了CommonJS)。此外,许多库/模块是为CommonJS编写的(通过向require
对象添加内容)而不是为AMD编写(通过从require
函数返回模块)。因此,许多支持Node的Web开发人员希望在Web上使用CommonJS库。这是可能的,因为从exports
标记加载是阻止的。像browserify这样的解决方案采用CommonJS(Node)模块并将它们包装起来,以便您可以将它们包含在脚本标记中。
因此,如果您正在为Web开发自己的多文件项目,我强烈推荐RequireJS,因为它确实是Web的模块系统(尽管在公平披露中,我发现AMD比CommonJS更自然)。最近,区别变得不那么重要了,因为RequireJS现在允许您基本上使用CommonJS语法。另外,RequireJS可用于在Node中加载AMD模块(虽然我更喜欢node-amd-loader)。
答案 0 :(得分:15)
结帐ender。它做了很多这个。
此外,browserify非常好。我使用了require-kiss并且它有效。可能还有其他人。
我不确定RequireJS。它与节点不同。从其他位置加载可能会遇到问题,但可能会有效。只要有提供方法或可以调用的东西。
TL; DR - 我建议使用browserify或require-kiss。
<强>更新强>
require-kiss现已死亡,作者已将其删除。我一直在使用RequireJS没有问题。 require-kiss的作者写了pakmanager和pakman。完全披露,我与开发人员合作。
我个人更喜欢RequireJS。它更容易调试(您可以在开发中使用单独的文件,在生产中使用单个部署的文件),并且构建在可靠的“标准”上。
答案 1 :(得分:12)
我写了一个小脚本,允许异步和同步加载Javascript文件,这可能在这里有用。它没有依赖关系,并且与Node.js兼容。 CommonJS的。您甚至可以将多个模块捆绑在一个文件中,以减少生产服务器上的HTTP请求。使用非常简单:
<script type="text/javascript" src="require.js"></script>
<script type="text/javascript">
var ModuleA = require('modulea') // Sync loading of a script in the module directory
ModuleA.funcA();
require('./path/moduleb.js', callbackB); // Async loading of a script anywhere else
function callbackB(ModuleB) {
ModuleB.funcB();
}
</script>
更多细节和代码可以在我的博客中找到:http://pixelsvsbytes.com/2013/02/js-require-for-browsers-better-faster-stronger/ 代码也在GitHub上:https://github.com/letorbi/smoothie/blob/master/standalone/require.js
答案 2 :(得分:9)
我意识到可能有一些初学者希望组织他们的代码。这是 2020 ,如果您正在考虑使用模块化JS应用,则应该立即开始使用 npm 和 Webpack 。
以下是一些简单的入门步骤:
npm init -y
初始化一个npm项目npm install webpack webpack-cli
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>App</title>
</head>
<body>
<script src="_bundle.js"></script>
</body>
</html>
请特别注意_bundle.js
文件-这将是由webpack生成的最终JS文件,您不会直接对其进行修改(请继续阅读)。
<project-root>/app.js
,您将在其中导入其他模块:const printHello = require('./print-hello');
printHello();
print-hello.js
模块:module.exports = function() {
console.log('Hello World!');
}
<project-root>/webpack.config.js
并复制并粘贴以下内容:var path = require('path');
module.exports = {
entry: './app.js',
output: {
path: path.resolve(__dirname),
filename: '_bundle.js'
}
};
在上面的代码中,有2点:
app.js
是编写JS代码的地方。它将导入其他模块,如上所示。_bundle.js
是webpack生成的最后一个包。这就是您的html末尾将看到的内容。 -7。打开您的package.js
,然后用以下命令替换scripts
:
"scripts": {
"start": "webpack --mode production -w"
},
app.js
并通过运行_bundle.js
来生成npm start
文件。答案 3 :(得分:7)
Ilya Kharlamov great answer的变体,有一些代码可以让它与Chrome开发人员工具配合使用。
//
///- REQUIRE FN
// equivalent to require from node.js
function require(url){
if (url.toLowerCase().substr(-3)!=='.js') url+='.js'; // to allow loading without js suffix;
if (!require.cache) require.cache=[]; //init cache
var exports=require.cache[url]; //get from cache
if (!exports) { //not cached
try {
exports={};
var X=new XMLHttpRequest();
X.open("GET", url, 0); // sync
X.send();
if (X.status && X.status !== 200) throw new Error(X.statusText);
var source = X.responseText;
// fix (if saved form for Chrome Dev Tools)
if (source.substr(0,10)==="(function("){
var moduleStart = source.indexOf('{');
var moduleEnd = source.lastIndexOf('})');
var CDTcomment = source.indexOf('//@ ');
if (CDTcomment>-1 && CDTcomment<moduleStart+6) moduleStart = source.indexOf('\n',CDTcomment);
source = source.slice(moduleStart+1,moduleEnd-1);
}
// fix, add comment to show source on Chrome Dev Tools
source="//@ sourceURL="+window.location.origin+url+"\n" + source;
//------
var module = { id: url, uri: url, exports:exports }; //according to node.js modules
var anonFn = new Function("require", "exports", "module", source); //create a Fn with module code, and 3 params: require, exports & module
anonFn(require, exports, module); // call the Fn, Execute the module
require.cache[url] = exports = module.exports; //cache obj exported by module
} catch (err) {
throw new Error("Error loading module "+url+": "+err);
}
}
return exports; //require returns object exported by module
}
///- END REQUIRE FN
答案 4 :(得分:5)
(function () {
// c is cache, the rest are the constants
var c = {},s="status",t="Text",e="exports",E="Error",r="require",m="module",S=" ",w=window;
w[r]=function R(url) {
url+=/.js$/i.test(url) ? "" : ".js";// to allow loading without js suffix;
var X=new XMLHttpRequest(),module = { id: url, uri: url }; //according to the modules 1.1 standard
if (!c[url])
try {
X.open("GET", url, 0); // sync
X.send();
if (X[s] && X[s] != 200)
throw X[s+t];
Function(r, e, m, X['response'+t])(R, c[url]={}, module); // Execute the module
module[e] && (c[url]=module[e]);
} catch (x) {
throw w[E](E+" in "+r+": Can't load "+m+S+url+":"+S+x);
}
return c[url];
}
})();
最好不要因为阻塞而在生产中使用。 (在node.js中,require()是一个阻塞调用很好)。
答案 5 :(得分:1)
Webmake将节点式模块捆绑到浏览器中,试一试。
答案 6 :(得分:1)
Require-stub - 在浏览器中提供符合节点的require
,解析模块和相对路径。使用类似于TKRequire(XMLHttpRequest)的技术。
生成的代码完全可浏览,require-stub
可以替代watchify
。
答案 7 :(得分:0)
以下是Lucio M. Tato的一个很棒的答案,它允许递归加载具有相对路径的模块。
以下是github project to house the solution以及如何使用它的示例:
https://github.com/trausti/TKRequire.js
要使用TKRequire.js,请在标题中包含以下行
&lt; script type =“text / javascript”src =“./ TKRequire.js”&gt;&lt; / script&gt;
然后像在node.js中一样加载模块:
var MyModule = require(“./ relative / path / to / MyModule.js”);