客户端的 JavaScript require()

Posted

技术标签:

【中文标题】客户端的 JavaScript require()【英文标题】:JavaScript require() on client side 【发布时间】:2011-07-07 07:25:08 【问题描述】:

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

示例

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

【问题讨论】:

【参考方案1】:

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

【讨论】:

@Debra:为什么不去他们网站上的“使用”部分? 看看Require(),如果你想要一个比 require.js、head.js 或 Lab.js 更轻量级的解决方案。 ... 或者现在您可以将客户端代码与大量工具捆绑在一起,例如 webpack 使用requirejs时,注意注意事项:***.com/questions/29652716/…。否则,对我有用。【参考方案2】:

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

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

【讨论】:

【参考方案3】:

如果你想要 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;

【讨论】:

我喜欢这个答案,因为它不是一个解决方案。当人们只是给出解决方案时,我真的很讨厌它。给出有助于他们下次找到解决方案的答案。干得好!【参考方案4】:

我问自己同样的问题。当我查看它时,我发现选择太多了。

幸运的是,我找到了这个出色的电子表格,可以帮助您根据自己的要求选择最佳加载器:

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

【讨论】:

我想知道电子​​表格的存在是否意味着我们作为开发人员还没有找到一个很好的方法来做到这一点?【参考方案5】:

看看requirejs 项目。

【讨论】:

【参考方案6】:

我发现通常建议在编译时预处理脚本并将它们捆绑在一个(或很少)包中,同时在编译时将 require 重写为一些“轻量级 shim”。

我已经在 Google 上搜索了应该能够做到这一点的“新”工具

http://mixu.net/gluejs/ https://github.com/jrburke/almond https://github.com/component/builder2.js

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

什么是模块系统?

旧堆栈溢出说明 - Relation between CommonJS, AMD and RequireJS?

各种模块框架的详细讨论以及他们需要的require()在Addy Osmani - Writing Modular JavaScript With AMD, CommonJS & ES Harmony中

【讨论】:

除了捆绑之外,它还允许在该捆绑中使用节点包吗?【参考方案7】:

您可以为加载项目的 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

【讨论】:

【参考方案8】:

只需使用 Browserify,类似于编译器的东西,它会在您的文件投入生产之前对其进行处理并将文件打包成包。

假设您有一个需要项目文件的 main.js 文件,当您在其中运行 browserify 时,它会简单地处理所有文件并创建一个包含所有文件的包,从而允许在其中同步使用 require 调用例如,浏览器没有 HTTP 请求,性能和包大小的开销非常小。

查看链接了解更多信息:http://browserify.org/

【讨论】:

Browserify 早在 2011 年就被 @dkastner 提到过。我在 Google 上搜索了一些替代方案,但我还不知道排名第一的解决方案【参考方案9】:

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

【讨论】:

【参考方案10】:

这是一个采用非常不同方法的解决方案:将所有模块打包成一个 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 样式的 require 语句并且对远程脚本加载解决方案不感兴趣的人最有帮助。

【讨论】:

【参考方案11】:

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

【讨论】:

【参考方案12】:

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

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

更多文档在这里:

https://github.com/mckoss/namespace

【讨论】:

【参考方案13】:

clientside-require库提供了一个异步的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 功能。免责声明:我已经编写了这个模块。

【讨论】:

某处是否有完整的工作示例?我正在尝试在客户端加载我自己的类,但它不起作用。【参考方案14】:

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

<script src="module.js"></script> 

然后像 js 文件中的用户

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

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

【讨论】:

以上是关于客户端的 JavaScript require()的主要内容,如果未能解决你的问题,请参考以下文章

基于socket.io客户端与服务端的相互通讯

node.js

实战Node.js之GET/POST请求在Web 应用架构在客户端的使用

require.js的使用

第一页

require.js ---- 基本使用