簡體   English   中英

客戶端的JavaScript require()

[英]JavaScript require() on client side

是否可以在客戶端使用require() (或類似的東西)?

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

您應該查看require.jshead.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

看看requirejs項目。

我發現一般情況下,建議在編譯時預處理腳本,並將它們捆綁在一個(或很少)包中,並在編譯時將require重寫為一些“輕量級填充程序”。

我已經使用了應該能夠執行此操作的“新”工具

而已經提到browserify也應該適應得不錯- http://esa-matti.suuronen.org/blog/2013/04/15/asynchronous-module-loading-with-browserify/

什么是模塊系統?

您可以為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時,它只是處理所有文件並創建一個包含所有文件的包,允許在沒有HTTP請求的情況下在瀏覽器中同步使用require調用例如,對於性能和捆綁的大小而言,開銷很小。

有關詳細信息,請參閱鏈接: 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不同,包不知道它的外部名稱。 這取決於包括依賴命名的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語句並且對遠程腳本加載解決方案不感興趣的人來說,這個答案最有幫助。

我發現組件項目比其他解決方案(包括require.js)提供了更加簡化的工作流程,因此我建議您查看https://github.com/component/component 我知道這是一個遲到的答案,但可能對某人有用。

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腳本中,你可以像在node.js中一樣使用同步require()函數!

例如,

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功能。 免責聲明:我已經寫過這個模塊。

這是在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

是的,它非常易於使用,但您需要通過腳本標記在瀏覽器中加載javascript文件

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

然后用戶在js文件中

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

我正在使用電子制作應用程序,它按預期工作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM