客户端的 JavaScript require()

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5168451/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 15:54:42  来源:igfitidea点击:

JavaScript require() on client side

javascriptnode.js

提问by Debra Maddux

Is it possible to use require()(or something similar) on client side?

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

Example

例子

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

回答by Andrew Hare

You should look into require.jsor head.jsfor this.

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

回答by dkastner

I've been using browserifyfor that. It also lets me integrate Node.js modules into my client-side code.

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

I blogged about it here: Add node.js/CommonJS style require() to client-side JavaScript with browserify

我在这里写了博客:使用browserify 将 node.js/CommonJS 样式 require() 添加到客户端 JavaScript

回答by Renaat De Muynck

If you want to have Node.js style requireyou can use something like this:

如果你想拥有 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;
}());

Beware: this code works but is incomplete (especially url resolving) and does not implement all Node.js features (I just put this together last night). YOU SHOULD NOT USE THIS CODEin real apps but it gives you a starting point. I tested it with this simple module and it works:

请注意:此代码有效但不完整(尤其是 url 解析)并且未实现所有 Node.js 功能(我昨晚刚刚将其放在一起)。 您不应在实际应用中使用此代码,但它为您提供了一个起点。我用这个简单的模块对其进行了测试,它可以工作:

function hello() {
    console.log('Hello world!');
}

exports.hello = hello;

回答by serby

I asked myself the very same questions. When I looked into it I found the choices overwhelming.

我问自己同样的问题。当我查看它时,我发现选择势不可挡。

Fortunately I found this excellent spreadsheet that helps you choice the best loader based on your requirements:

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

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

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

回答by gor

Take a look at requirejsproject.

看看requirejs项目。

回答by xmojmr

I have found that in general it is recommended to preprocess scripts at compile time and bundle them in one (or very few) packages with the requirebeing rewritten to some "lightweight shim" also at compile time.

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

I've Googled out following "new" tools that should be able to do it

我在谷歌上搜索了应该能够做到的“新”工具

And the already mentioned browserifyshould also fit quite well - http://esa-matti.suuronen.org/blog/2013/04/15/asynchronous-module-loading-with-browserify/

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

What are the module systems all about?

模块系统是什么?

回答by Andre Backlund

You can create elements to the DOM, which loads items.

您可以为 DOM 创建元素,该 DOM 会加载项目。

Like such:

像这样:

var myScript = document.createElement('script'); // Create new script element
myScript.type = 'text/javascript'; // Set appropriate type
myScript.src = './js/myclass.js'; // Load javascript file

回答by Fernando Mota

Simply use Browserify, what is something like a compiler that process your files before it go into production and packs the file in bundles.

只需使用 Browserify,它就像一个编译器,可以在您的文件投入生产之前对其进行处理并将文件打包成包。

Think you have a main.js file that require the files of your project, when you run browserify in it, it simply process all and creates a bundle with all your files, allowing the use of the requirecalls synchronously in the browser without HTTP requests and with very little overhead for the performance and for the size of the bundle, for example.

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

See the link for more info: http://browserify.org/

有关更多信息,请参阅链接:http: //browserify.org/

回答by M?rre

Some answers already - but I would like to point you to YUI3 and its on-demand module loading. It works on both server (node.js) and client, too - I have a demo website using the exact same JS code running on either client or server to build the pages, but that's another topic.

已经有一些答案 - 但我想向您指出 YUI3 及其按需模块加载。它也适用于服务器 (node.js) 和客户端 - 我有一个演示网站,使用在客户端或服务器上运行的完全相同的 JS 代码来构建页面,但这是另一个主题。

YUI3: http://developer.yahoo.com/yui/3/

YUI3:http: //developer.yahoo.com/yui/3/

Videos: http://developer.yahoo.com/yui/theater/

视频:http: //developer.yahoo.com/yui/theater/

Example:

例子:

(precondition: the basic YUI3 functions in 7k yui.js have been loaded)

(前提: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
}

This code loads the YUI3 modules "node" and "io", and the module "own-app-module1", and then the callback function is run. A new sandbox "Y" with all the YUI3 and own-app-module1 functions is created. Nothing appears in the global namespace. The loading of the modules (.js files) is handled by the YUI3 loader. It also uses (optional, not show here) configuration to select a -debug or -min(ified) version of the modules to load.

此代码加载 YUI3 模块“node”和“io”,以及模块“own-app-module1”,然后运行回调函数。创建了一个包含所有 YUI3 和 own-app-module1 功能的新沙箱“Y”。全局命名空间中没有任何内容。模块(.js 文件)的加载由 YUI3 加载器处理。它还使用(可选,此处未显示)配置来选择要加载的模块的 -debug 或 -min(ified) 版本。

回答by Daniel X Moore

Here's a solution that takes a very different approach: package up all the modules into a JSON object and require modules by reading and executing the file content without additional requests.

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

https://github.com/STRd6/require/blob/master/main.coffee.md

https://github.com/STRd6/require/blob/master/main.coffee.md

STRd6/requiredepends on having a JSON package available at runtime. The requirefunction is generated for that package. The package contains all the files your app could require. No further http requests are made because the package bundles all dependencies. This is as close as one can get to the Node.js style require on the client.

STRd6/require依赖于在运行时可用的 JSON 包。该require函数是为该包生成的。该包包含您的应用程序可能需要的所有文件。不再发出 http 请求,因为该包捆绑了所有依赖项。这与客户端要求的 Node.js 风格非常接近。

The structure of the package is as follows:

包的结构如下:

entryPoint: "main"
distribution:
  main: 
    content: "alert(\"It worked!\")"
  ...
dependencies:
  <name>: <a package>

Unlike Node a package doesn't know it's external name. It is up to the pacakge including the dependency to name it. This provides complete encapsulation.

与 Node 不同,包不知道它的外部名称。由包含依赖项的 pacakge 来命名它。这提供了完整的封装。

Given all that setup here's a function that loads a file from within a package:

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

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

This external context provides some variable that modules have access to.

这个外部上下文提供了一些模块可以访问的变量。

A requirefunction is exposed to modules so they may require other modules.

一个require函数暴露给模块,所以它们可能需要其他模块。

Additional properties such as a reference to the global object and some metadata are also exposed.

还公开了其他属性,例如对全局对象的引用和一些元数据。

Finally we execute the program within the module and given context.

最后,我们在模块和给定的上下文中执行程序。

This answer will be most helpful to those who wish to have a synchronous node.js style require statement in the browser and are not interested in remote script loading solutions.

这个答案对那些希望在浏览器中使用同步 node.js 样式的 require 语句并且对远程脚本加载解决方案不感兴趣的人最有帮助。