客户端的JavaScript require()

时间:2011-03-02 13:59:25

标签: javascript node.js

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

示例

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

14 个答案:

答案 0 :(得分:41)

您应该查看require.jshead.js

答案 1 :(得分:22)

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

我在这里写了博客:Add node.js/CommonJS style require() to client-side JavaScript with browserify

答案 2 :(得分:13)

如果您想拥有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;

答案 3 :(得分:12)

我问自己同样的问题。当我调查它时,我发现选择压倒性的。

幸运的是,我发现这个优秀的电子表格可以帮助您根据自己的要求选择最好的装载机:

https://spreadsheets.google.com/lv?key=tDdcrv9wNQRCNCRCflWxhYQ

答案 4 :(得分:9)

看看requirejs项目。

答案 5 :(得分:7)

我发现一般情况下,建议在编译时预处理脚本并将它们捆绑在一个(或很少)包中,并将require重写为某些"轻量级垫片"也是在编译时。

我已经跟随"新"应该能够做到的工具

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

模块系统有哪些?

答案 6 :(得分:4)

您可以为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

答案 7 :(得分:3)

简单地使用Browserify,类似于编译器,它可以在文件投入生产之前对其进行处理,并将文件打包成捆绑包。

认为你有一个需要项目文件的main.js文件,当你在其中运行browserify时,它只是处理所有文件并创建一个包含所有文件的包,允许使用require个调用例如,在没有HTTP请求的浏览器中同步,并且对性能和包的大小的开销很小。

有关详细信息,请参阅该链接:http://browserify.org/

答案 8 :(得分:2)

已经有了一些答案 - 但我想指出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)版本。

答案 9 :(得分:1)

这是一个采用非常不同的方法的解决方案:将所有模块打包成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不同,包不知道它的外部名称。这取决于包括依赖命名的pacakge。这提供了完整的封装。

鉴于所有这些设置,这里是一个从包中加载文件的函数:

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 style require语句并且对远程脚本加载解决方案不感兴趣的人来说,这个答案最有帮助。

答案 10 :(得分:1)

我发现组件项目比其他解决方案(包括require.js)提供了更加简化的工作流程,因此我建议您查看https://github.com/component/component。我知道这有点迟,但可能对某人有用。

答案 11 :(得分:0)

这是一种在Web客户端中使用require和exports的轻量级方法。它是一个创建“命名空间”全局变量的简单包装器,并将您的CommonJS兼容代码包装在“define”函数中,如下所示:

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

此处有更多文档:

https://github.com/mckoss/namespace

答案 12 :(得分:0)

The clientside-require library provides an asynchronous load() function that can be used to load any JS file or NPM module (which uses module.exports), any .css file, any .json, any .html, any any other file as text.

e.g., 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>

A really cool part of this project is that inside of any load()ed script, you can use the synchronous require() function the same way you would expect in node.js!

e.g.,

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

and inside /path/to/functionality.js:

var query_string = require("qs") // an npm module
module.exports = function(name){
    return qs.stringify({
         name:name,
         time:new Date()
    }
}

That last part, implementing the synchronous require() method, is what enables it to utilize NPM packages built to run on the server.


This module was designed to implement the require functionality as closely as possible in the browser. Disclaimer: I have written this module.

答案 13 :(得分:-4)

是的,它非常易于使用,但您需要通过脚本标记

在浏览器中加载javascript文件
<script src="module.js"></script> 

然后用户在js文件中

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

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