Чи можна використовувати require()(або щось подібне) на стороні клієнта?
Приклад
var myClass = require('./js/myclass.js');
Чи можна використовувати require()(або щось подібне) на стороні клієнта?
Приклад
var myClass = require('./js/myclass.js');
Відповіді:
Ви повинні дивитися на require.js або head.js для цього.
Для цього я використовую browserify . Це також дозволяє мені інтегрувати модулі Node.js у мій код на стороні клієнта.
Я писав про це в блозі тут: Додайте стиль node.js / CommonJS require () до JavaScript на стороні клієнта за допомогою browserify
Якщо ви хочете мати стиль 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
Я виявив, що загалом рекомендується попередньо обробляти сценарії під час компіляції та згрупувати їх в один (або дуже мало) пакунків require, перезаписуючи на якусь "легку шим" також під час компіляції.
Я погуглив за наступними "новими" інструментами, які повинні це зробити
І вже згадане browserifyтакож повинно цілком відповідати - http://esa-matti.suuronen.org/blog/2013/04/15/asynchronous-module-loading-with-browserify/
Попереднє пояснення переповнення стека - Співвідношення між CommonJS, AMD та RequireJS?
Детальне обговорення різних фреймворків модулів та їхніх require()потреб знаходиться в Addy Osmani - Написання модульного JavaScript з AMD, CommonJS та ES Harmony
Ви можете створювати елементи в 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, для якого потрібні файли вашого проекту; коли ви запускаєте в ньому браузер, він просто обробляє все і створює пакет з усіма вашими файлами, дозволяючи requireсинхронно використовувати дзвінки у браузері без запитів HTTP та наприклад, з дуже невеликими накладними витратами на продуктивність та розмір комплекту.
Див. Посилання для отримання додаткової інформації: http://browserify.org/
Уже є деякі відповіді - але я хотів би вказати вам на 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) версії модулів для завантаження.
Ось рішення, яке застосовує зовсім інший підхід: упакуйте всі модулі в об’єкт 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.js), тому я радив би перевірити https://github.com/component/component . Я знаю, що це трохи пізня відповідь, але може бути корисною комусь.
Ось легкий спосіб використання вимог та експорту у вашому веб-клієнті. Це проста обгортка, яка створює глобальну змінну "простору імен", і ваш код, сумісний із CommonJS, обертається функцією "define", як це:
namespace.lookup('org.mydomain.mymodule').define(function (exports, require) {
var extern = require('org.other.module');
exports.foo = function foo() { ... };
});
Більше документів тут:
Клієнтська-вимагається бібліотека забезпечує асинхронну 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функціоналу якомога тісніше у браузері. Застереження: Я написав цей модуль.
Так, він дуже простий у використанні, але вам потрібно завантажити файл javascript у браузер за тегом сценарію
<script src="module.js"></script>
а потім користувач у файлі js, як
var moduel = require('./module');
Я роблю додаток, використовуючи електрон, і він працює, як очікувалося.