是否可以require()在客户端使用(或类似方法)?
例
var myClass = require('./js/myclass.js');
是否可以require()在客户端使用(或类似方法)?
例
var myClass = require('./js/myclass.js');
Answers:
你应该看看require.js或head.js这一点。
我一直在使用browserify。它还使我可以将Node.js模块集成到我的客户端代码中。
我在这里写过博客:使用browserify将node.js / CommonJS样式require()添加到客户端JavaScript
如果您想拥有Node.js样式require,可以使用以下代码:
var require = (function () {
var cache = {};
function loadScript(url) {
var xhr = new XMLHttpRequest(),
fnBody;
xhr.open('get', url, false);
xhr.send();
if (xhr.status === 200 && xhr.getResponseHeader('Content-Type') === 'application/x-javascript') {
fnBody = 'var exports = {};\n' + xhr.responseText + '\nreturn exports;';
cache[url] = (new Function(fnBody)).call({});
}
}
function resolve(module) {
//TODO resolve urls
return module;
}
function require(module) {
var url = resolve(module);
if (!Object.prototype.hasOwnProperty.call(cache, url)) {
loadScript(url);
}
return cache[url];
}
require.cache = cache;
require.resolve = resolve;
return require;
}());
当心:此代码有效,但不完整(尤其是URL解析),并且未实现所有Node.js功能(我昨晚才将其组合在一起)。 您不应该在实际应用中使用此代码,但是它可以为您提供一个起点。我使用这个简单的模块对其进行了测试,并且可以正常工作:
function hello() {
console.log('Hello world!');
}
exports.hello = hello;
我问自己同样的问题。当我查看它时,发现选择不胜枚举。
幸运的是,我发现了这个出色的电子表格,可以帮助您根据自己的需求选择最佳的装载机:
https://spreadsheets.google.com/lv?key=tDdcrv9wNQRCNCRCflWxhYQ
我发现通常建议在编译时对脚本进行预处理,然后将它们捆绑在一个(或很少)包中,require并在编译时将其重写为某些“轻量级填充”。
我已经搜索了应该可以使用的“新”工具
而且已经提到的内容browserify也应该非常合适-http: //esa-matti.suuronen.org/blog/2013/04/15/asynchronous-module-loading-with-browserify/
较早的堆栈溢出说明-CommonJS,AMD和RequireJS之间的关系?
有关各种模块框架及其require()需求的详细讨论,请参见Addy Osmani-使用AMD,CommonJS和ES Harmony编写模块化JavaScript
您可以为DOM创建元素,以加载项目。
像这样:
var myScript = document.createElement('script'); // Create new script element
myScript.type = 'text/javascript'; // Set appropriate type
myScript.src = './js/myclass.js'; // Load javascript file
只需使用Browserify,这就像是编译器,可以在文件投入生产之前先处理文件,然后将文件打包成捆。
认为您有一个需要项目文件的main.js文件,当您在其中运行browserify时,它会简单地处理所有文件并创建包含所有文件的捆绑包,从而允许require在浏览器中同步使用调用,而无需HTTP请求和例如,在性能和捆绑包大小方面的开销很小。
有关更多信息,请参见链接:http : //browserify.org/
已经有一些答案-但我想向您指出YUI3及其按需加载模块。它也可以在服务器(node.js)和客户端上使用-我有一个演示网站,该网站使用在客户端或服务器上运行的完全相同的JS代码来构建页面,但这是另一个主题。
YUI3:http://developer.yahoo.com/yui/3/
视频:http : //developer.yahoo.com/yui/theater/
例:
(前提:7k yui.js中的基本YUI3函数已加载)
YUI({
//configuration for the loader
}).use('node','io','own-app-module1', function (Y) {
//sandboxed application code
//...
//If you already have a "Y" instance you can use that instead
//of creating a new (sandbox) Y:
// Y.use('moduleX','moduleY', function (Y) {
// });
//difference to YUI().use(): uses the existing "Y"-sandbox
}
此代码加载YUI3模块“ node”和“ io”以及模块“ own-app-module1”,然后运行回调函数。创建具有所有YUI3和own-app-module1功能的新沙箱“ Y”。全局名称空间中没有任何内容。模块(.js文件)的加载由YUI3加载器处理。它还使用(可选,此处未显示)配置选择要加载的模块的-debug或-min(ified)版本。
这是采用不同方法的解决方案:将所有模块打包为JSON对象,并通过读取和执行文件内容来获得模块,而无需其他请求。
https://github.com/STRd6/require/blob/master/main.coffee.md
STRd6 / require取决于在运行时是否提供JSON包。该require函数是为该软件包生成的。该软件包包含您的应用可能需要的所有文件。由于该软件包捆绑了所有依赖项,因此不再发出http请求。这与客户端上所需的Node.js样式几乎一样。
软件包的结构如下:
entryPoint: "main"
distribution:
main:
content: "alert(\"It worked!\")"
...
dependencies:
<name>: <a package>
与Node不同,软件包不知道它的外部名称。取决于名称的依赖关系。这提供了完整的封装。
在完成所有设置后,这里提供了一个从包中加载文件的功能:
loadModule = (pkg, path) ->
unless (file = pkg.distribution[path])
throw "Could not find file at #{path} in #{pkg.name}"
program = file.content
dirname = path.split(fileSeparator)[0...-1].join(fileSeparator)
module =
path: dirname
exports: {}
context =
require: generateRequireFn(pkg, module)
global: global
module: module
exports: module.exports
PACKAGE: pkg
__filename: path
__dirname: dirname
args = Object.keys(context)
values = args.map (name) -> context[name]
Function(args..., program).apply(module, values)
return module
该外部上下文提供了模块可以访问的一些变量。
一个require功能公开给模块,因此它们可能需要其他模块。
还公开了其他属性,例如对全局对象的引用和一些元数据。
最后,我们在模块和给定的上下文中执行程序。
对于希望在浏览器中具有同步node.js样式的require语句并且对远程脚本加载解决方案不感兴趣的人,此答案将最有帮助。
我发现与其他解决方案(包括require.js)相比,该组件项目提供了更为简化的工作流程,因此建议您查看https://github.com/component/component。我知道这是一个较晚的答案,但可能对某人有用。
这是在Web客户端中使用需求和导出的轻量级方法。这是一个简单的包装程序,它创建一个“命名空间”全局变量,然后将您的CommonJS兼容代码包装在一个“定义”函数中,如下所示:
namespace.lookup('org.mydomain.mymodule').define(function (exports, require) {
var extern = require('org.other.module');
exports.foo = function foo() { ... };
});
此处有更多文档:
在客户机侧,需要库提供一个异步load()可用于加载任何JS文件或NPM模块(使用功能module.exports),任何.css文件,任何.json,任何.html,任何其他文件为文本。
例如,
npm install clientside-require --save
<script src = '/node_modules/clientside-require/dist/bundle.js'></script>
<script>
load('color-name') // an npm module
.then(color_name=>{
console.log(color_name.blue); // outputs [0, 0, 255]
})
</script>
该项目的一个非常酷的部分是,在任何load()ed脚本中,您都可以按照require()在node.js中期望的方式使用同步功能!
例如,
load('/path/to/functionality.js')
里面/path/to/functionality.js:
var query_string = require("qs") // an npm module
module.exports = function(name){
return qs.stringify({
name:name,
time:new Date()
}
}
最后一部分,实现同步require()方法,使它能够利用为在服务器上运行而构建的NPM软件包。
该模块旨在require在浏览器中尽可能紧密地实现功能。免责声明:我已经编写了此模块。