关于node.js:客户端的JavaScript require()

JavaScript require() on client side

是否可以在客户端使用require()(或类似的东西)?

例子

1
var myClass = require('./js/myclass.js');

为此,您应该查看require.js或head.js。


我一直在使用browserify。它还允许我将node.js模块集成到客户端代码中。

我在这里写了一篇博客:使用browserify将node.js/commonjs-style require()添加到客户端javascript


如果要使用node.js样式的require,可以使用如下内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
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 = {};
'
+ xhr.responseText + '
return 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特性(我昨晚刚刚把它放在一起)。你不应该在真正的应用程序中使用这个代码,但它给了你一个起点。我用这个简单的模块测试了它,它工作:

1
2
3
4
5
function hello() {
    console.log('Hello world!');
}

exports.hello = hello;


我问自己同样的问题。当我研究它的时候,我发现选择是压倒性的。

幸运的是,我发现了这个优秀的电子表格,它可以帮助您根据您的需求选择最佳的加载程序:

https://spreadsheets.google.com/lv?键=TDDCRV9WnqRncrCfLwxHyQ


看看RequireJS项目。


我发现,通常建议在编译时对脚本进行预处理,并将它们捆绑在一个(或极少数)包中,同时在编译时将require重写为一些"轻量级填充程序"。

我在谷歌上搜索了以下"新"工具,应该可以做到这一点

  • 网址:http://mixu.net/gluejs/
  • https://github.com/jrburke/杏仁
  • https://github.com/component/builder2.js网站

已经提到的browserify也应该很适合-http://esa-matti.suuronen.org/blog/2013/04/15/asynchronous-module-loading-with-browserify/

模块系统都是关于什么的?

  • 旧的堆栈溢出说明-CommonJS、AMD和RequireJS之间的关系?

  • 详细讨论了各种模块框架和它们需要的require()是在addy osmani中编写的模块化javascript与AMD、CommonJS&es Harmony


您可以创建加载项的DOM元素。

就像这样:

1
2
3
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基本功能已经加载)

1
2
3
4
5
6
7
8
9
10
11
12
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",然后运行回调函数。创建了一个新的沙盒"y",其中包含所有yui3和own-app-module1函数。全局命名空间中没有显示任何内容。模块(.js文件)的加载由yui3加载程序处理。它还使用(可选,此处不显示)配置来选择要加载的模块的-debug或-min(化)版本。


我发现组件项目提供了比其他解决方案(包括require.js)更精简的工作流,所以我建议您签出https://github.com/component/component。我知道这个回答有点晚,但可能对某人有用。


这里的解决方案采用了一种非常不同的方法:将所有模块打包到一个JSON对象中,通过读取和执行文件内容而不需要额外的请求来要求模块。

https://github.com/strd6/require/blob/master/main.coffee.md网站

strd6/require取决于运行时是否有可用的JSON包。为该包生成require函数。该包包含应用程序可能需要的所有文件。没有进一步的HTTP请求,因为包捆绑了所有依赖项。这是尽可能接近客户机上需要的node.js样式。

包装结构如下:

1
2
3
4
5
6
7
entryPoint:"main"
distribution:
  main:
    content:"alert("It worked!")"
  ...
dependencies:
  <name>:

与节点不同,包不知道它的外部名称。它取决于pacakge,包括命名它的依赖关系。这提供了完整的封装。

考虑到所有这些设置,这里有一个函数可以从包中加载文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
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功能暴露于模块中,因此可能需要其他模块。

其他属性,如对全局对象的引用和一些元数据也暴露在外。

最后,我们在模块内执行程序并给出上下文。

对于那些希望在浏览器中使用synchronous node.js风格的require语句并且对远程脚本加载解决方案不感兴趣的人来说,这个答案非常有用。


客户端需求库提供异步load()功能,可用于加载任何JS文件或NPM模块(使用module.exports、任何.css文件、任何.json、任何.html、任何其他文本文件。

例如。,埃多克斯1〔9〕

1
2
3
4
5
6
<script src = '/node_modules/clientside-require/dist/bundle.js'>

load('color-name') // an npm module
   .then(color_name=>{
        console.log(color_name.blue); // outputs  [0, 0, 255]
   })

这个项目的一个很酷的部分是,在任何load()ed脚本中,您可以像在node.js中预期的那样使用同步require()函数!

例如。,

1
load('/path/to/functionality.js')

/path/to/functionality.js内:

1
2
3
4
5
6
7
var query_string = require("qs") // an npm module
module.exports = function(name){
    return qs.stringify({
         name:name,
         time:new Date()
    }
}

最后一部分,实现同步require()方法,使其能够利用构建在服务器上运行的NPM包。

该模块旨在尽可能在浏览器中实现require功能。免责声明:我已经编写了这个模块。


这是一种在Web客户机中使用需求和导出的轻量级方法。它是一个创建"namespace"全局变量的简单包装器,您可以将与CommonJS兼容的代码包装在"define"函数中,如下所示:

1
2
3
4
namespace.lookup('org.mydomain.mymodule').define(function (exports, require) {
    var extern = require('org.other.module');
    exports.foo = function foo() { ... };
});

此处显示更多文档:

https://github.com/mckoss/命名空间


是的,它很容易使用,但您需要在浏览器中通过脚本标记加载javascript文件。

1
<script src="module.js">

然后用户在JS文件中

1
var moduel = require('./module');

我正在用电子制作一个应用程序,它按预期工作。