JavaScript вимагає () на стороні клієнта


83

Чи можна використовувати require()(або щось подібне) на стороні клієнта?

Приклад

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

Відповіді:


41

Ви повинні дивитися на require.js або head.js для цього.


5
@Debra: Чому б не перейти до розділу "Використання" на їх веб-сайті?
Гонки легкості на орбіті

2
Погляньте на Require () , якщо ви хочете отримати більш легке рішення, ніж require.js, head.js або Lab.js.
Торбен

2
... або в ці дні ви можете поєднати код на стороні клієнта з безліччю інструментів, таких як webpack
Aprillion

При використанні requirejs зверніть увагу на застереження: stackoverflow.com/questions/29652716/… . В іншому випадку це працює для мене.
user180574


14

Якщо ви хочете мати стиль 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
Мені сподобалась ця відповідь, оскільки це не рішення. Я дуже ненавиджу, коли люди просто дають рішення. Дайте відповідь, яка допоможе їм знайти рішення наступного разу. Чудова робота!
Жасмин

13

Я задавав собі ті самі запитання. Коли я заглянув у це, то виявив, що вибір надзвичайний.

На щастя, я знайшов цю чудову електронну таблицю, яка допомагає вибрати найкращий навантажувач на основі ваших вимог:

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


1
Цікаво, чи наявність електронної таблиці варіантів означає, що ми як розробники ще не знайшли чудового способу зробити це?
Коста


7

Я виявив, що загалом рекомендується попередньо обробляти сценарії під час компіляції та згрупувати їх в один (або дуже мало) пакунків require, перезаписуючи на якусь "легку шим" також під час компіляції.

Я погуглив за наступними "новими" інструментами, які повинні це зробити

І вже згадане browserifyтакож повинно цілком відповідати - http://esa-matti.suuronen.org/blog/2013/04/15/asynchronous-module-loading-with-browserify/

Що таке модульні системи?


І окрім комплектування, це також дозволяє використовувати пакети вузлів із цього пакета?
eran otzap

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

4

Просто використовуйте Browserify, щось на зразок компілятора, який обробляє ваші файли до того, як він увійде у виробництво, і упакує файл у пакети.

Подумайте, у вас є файл main.js, для якого потрібні файли вашого проекту; коли ви запускаєте в ньому браузер, він просто обробляє все і створює пакет з усіма вашими файлами, дозволяючи requireсинхронно використовувати дзвінки у браузері без запитів HTTP та наприклад, з дуже невеликими накладними витратами на продуктивність та розмір комплекту.

Див. Посилання для отримання додаткової інформації: http://browserify.org/


Про Browserify вже згадував @dkastner ще в 2011 році. У своїй відповіді я погуглив кілька альтернатив, але поки не знаю рішення №1
xmojmr

2

Уже є деякі відповіді - але я хотів би вказати вам на YUI3 та його завантаження модулів на вимогу. Це працює як на сервері (node.js), так і на клієнті - у мене є демонстраційний веб-сайт, який використовує той самий код JS, який працює на клієнті або сервері для створення сторінок, але це вже інша тема.

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

Відео: http://developer.yahoo.com/yui/theater/

Приклад:

(передумова: основні функції YUI3 в 7k yui.js завантажені)

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 "вузол" та "io", а також модуль "own-app-module1", після чого запускається функція зворотного виклику. Створено нову пісочницю "Y" з усіма функціями YUI3 та власним додатком-модулем1. У глобальному просторі імен нічого не відображається. Завантаженням модулів (файли .js) займається завантажувач YUI3. Він також використовує (необов’язково, не показувати тут) конфігурацію для вибору -debug або -min (ified) версії модулів для завантаження.


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, який вимагає заявки у браузері і не зацікавлений у рішеннях для віддаленого завантаження скриптів.


1

Я вважаю, що проект компонентів надає набагато впорядкованіший робочий процес, ніж інші рішення (включаючи require.js), тому я радив би перевірити https://github.com/component/component . Я знаю, що це трохи пізня відповідь, але може бути корисною комусь.


0

Ось легкий спосіб використання вимог та експорту у вашому веб-клієнті. Це проста обгортка, яка створює глобальну змінну "простору імен", і ваш код, сумісний із 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


0

Клієнтська-вимагається бібліотека забезпечує асинхронну load()функцію , яка може бути використана для завантаження будь-якого файлу JS або модуля ного (який використовує 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функціоналу якомога тісніше у браузері. Застереження: Я написав цей модуль.


Чи є десь повний робочий приклад? Я намагаюся завантажити власні класи на стороні клієнта, і це не буде працювати.
джалмер

-4

Так, він дуже простий у використанні, але вам потрібно завантажити файл javascript у браузер за тегом сценарію

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

а потім користувач у файлі js, як

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

Я роблю додаток, використовуючи електрон, і він працює, як очікувалося.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.