Czy można używać require()(lub czegoś podobnego) po stronie klienta?
Przykład
var myClass = require('./js/myclass.js');
Czy można używać require()(lub czegoś podobnego) po stronie klienta?
Przykład
var myClass = require('./js/myclass.js');
Odpowiedzi:
Należy spojrzeć na require.js lub head.js dla tego produktu.
Używam do tego browserify . Pozwala mi także zintegrować moduły Node.js z moim kodem po stronie klienta.
Napisałem o tym na blogu tutaj: Dodaj styl node.js / CommonJS require () do JavaScript po stronie klienta za pomocą browserify
Jeśli chcesz mieć styl Node.js require, możesz użyć czegoś takiego:
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;
}());
Uwaga: ten kod działa, ale jest niekompletny (szczególnie w przypadku rozwiązywania adresów URL) i nie implementuje wszystkich funkcji Node.js (właśnie złożyłem to zeszłej nocy). NIE WOLNO UŻYWAĆ TEGO KODU w prawdziwych aplikacjach, ale daje on punkt wyjścia. Przetestowałem to z tym prostym modułem i działa:
function hello() {
console.log('Hello world!');
}
exports.hello = hello;
Zadałem sobie te same pytania. Kiedy przyjrzałem się temu, stwierdziłem, że wybory są przytłaczające.
Na szczęście znalazłem ten doskonały arkusz kalkulacyjny, który pomoże Ci wybrać najlepszy program ładujący w oparciu o Twoje wymagania:
https://spreadsheets.google.com/lv?key=tDdcrv9wNQRCNCRCflWxhYQ
Zauważyłem, że generalnie zaleca się wstępne przetwarzanie skryptów w czasie kompilacji i łączenie ich w jeden (lub kilka) pakietów z require przepisywaniem ich do jakiejś „lekkiej podkładki”, również w czasie kompilacji.
Wygooglowałem następujące „nowe” narzędzia, które powinny to zrobić
A wspomniane już browserifypowinno też całkiem nieźle pasować - http://esa-matti.suuronen.org/blog/2013/04/15/asynchronous-module-loading-with-browserify/
Starsze wyjaśnienie przepełnienia stosu - związek między CommonJS, AMD i RequireJS?
Szczegółowe omówienie różnych frameworków modułów i require()ich potrzeb znajduje się w Addy Osmani - Writing Modular JavaScript with AMD, CommonJS & ES Harmony
Możesz tworzyć elementy do DOM, który ładuje elementy.
Jak takie:
var myScript = document.createElement('script'); // Create new script element
myScript.type = 'text/javascript'; // Set appropriate type
myScript.src = './js/myclass.js'; // Load javascript file
Po prostu użyj Browserify, czegoś w rodzaju kompilatora, który przetwarza twoje pliki przed przejściem do produkcji i pakuje plik w pakiety.
Myślisz, że masz plik main.js, który wymaga plików twojego projektu, kiedy uruchomisz w nim przeglądarkę, po prostu przetwarza wszystko i tworzy pakiet ze wszystkimi plikami, umożliwiając użycie require synchroniczne wywołań w przeglądarce bez żądań HTTP i na przykład z bardzo małym narzutem na wydajność i rozmiar pakietu.
Zobacz link, aby uzyskać więcej informacji: http://browserify.org/
Kilka odpowiedzi już - ale chciałbym wskazać wam YUI3 i jego ładowanie modułu na żądanie. Działa zarówno na serwerze (node.js), jak i na kliencie - mam witrynę demonstracyjną używającą dokładnie tego samego kodu JS działającego na kliencie lub serwerze do tworzenia stron, ale to inny temat.
YUI3: http://developer.yahoo.com/yui/3/
Filmy: http://developer.yahoo.com/yui/theater/
Przykład:
(warunek wstępny: podstawowe funkcje YUI3 w 7k yui.js zostały załadowane)
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
}
Ten kod ładuje moduły YUI3 „node” i „io” oraz moduł „own-app-module1”, a następnie uruchamiana jest funkcja zwrotna. Utworzono nową piaskownicę "Y" ze wszystkimi funkcjami YUI3 i own-app-module1. W globalnej przestrzeni nazw nic nie pojawia się. Ładowanie modułów (plików .js) jest obsługiwane przez moduł ładujący YUI3. Używa również (opcjonalnej, nie pokazanej tutaj) konfiguracji do wybrania wersji -debug lub -min (ified) modułów do załadowania.
Oto rozwiązanie, które ma zupełnie inne podejście: spakuj wszystkie moduły do obiektu JSON i wymagaj modułów, odczytując i wykonując zawartość pliku bez dodatkowych żądań.
https://github.com/STRd6/require/blob/master/main.coffee.md
STRd6 / require zależy od posiadania pakietu JSON dostępnego w czasie wykonywania. requireFunkcja jest generowany dla tego pakietu. Pakiet zawiera wszystkie pliki, których może wymagać Twoja aplikacja. Żadne dalsze żądania http nie są wysyłane, ponieważ pakiet zawiera wszystkie zależności. Jest to tak blisko, jak tylko można uzyskać od stylu Node.js wymaganego na kliencie.
Struktura pakietu jest następująca:
entryPoint: "main"
distribution:
main:
content: "alert(\"It worked!\")"
...
dependencies:
<name>: <a package>
W przeciwieństwie do Node pakiet nie zna swojej nazwy zewnętrznej. To zależy od pakietu, w tym zależności, aby go nazwać. Zapewnia to całkowitą hermetyzację.
Biorąc pod uwagę całą tę konfigurację, oto funkcja, która ładuje plik z pakietu:
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
Ten kontekst zewnętrzny zapewnia pewną zmienną, do której moduły mają dostęp.
ZA requireFunkcja jest narażona na modułach więc mogą wymagać inne moduły.
Dodatkowe właściwości, takie jak odwołanie do obiektu globalnego i niektóre metadane, są również ujawniane.
Na koniec wykonujemy program w ramach modułu i w danym kontekście.
Ta odpowiedź będzie najbardziej pomocna dla tych, którzy chcą mieć synchroniczny styl node.js, wymagają instrukcji w przeglądarce i nie są zainteresowani rozwiązaniami do zdalnego ładowania skryptów.
Uważam, że projekt komponentu zapewnia znacznie bardziej usprawniony przepływ pracy niż inne rozwiązania (w tym require.js), więc radziłbym sprawdzić https://github.com/component/component . Wiem, że to trochę późna odpowiedź, ale może się komuś przydać.
Oto lekki sposób korzystania z wymagania i eksportu w kliencie WWW. Jest to proste opakowanie, które tworzy zmienną globalną „przestrzeni nazw”, a kod zgodny z CommonJS opakowujesz w funkcję „definiuj” w następujący sposób:
namespace.lookup('org.mydomain.mymodule').define(function (exports, require) {
var extern = require('org.other.module');
exports.foo = function foo() { ... };
});
Więcej dokumentów tutaj:
Stronie klienta, wymaga biblioteki zapewnia asynchroniczny load()funkcji, które można wykorzystać, aby załadować dowolny plik JS lub moduł NPM (który używa module.exports), dowolny .cssplik, każdy .json, dowolny.html , każdy każdy inny plik jako tekst.
na przykład,
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>
Naprawdę fajną częścią tego projektu jest to, że w każdym load()skrypcie ed możesz używać require()funkcji synchronicznej w taki sam sposób, jakiego można by oczekiwać w node.js!
na przykład,
load('/path/to/functionality.js')
a wewnątrz /path/to/functionality.js:
var query_string = require("qs") // an npm module
module.exports = function(name){
return qs.stringify({
name:name,
time:new Date()
}
}
Ta ostatnia część, implementująca require()metodę synchroniczną , umożliwia wykorzystanie pakietów NPM zbudowanych do działania na serwerze.
Ten moduł został zaprojektowany w celu requirejak najściślejszej implementacji funkcjonalności w przeglądarce. Zastrzeżenie: napisałem ten moduł.
Tak, jest bardzo łatwy w użyciu, ale musisz załadować plik javascript w przeglądarce za pomocą tagu skryptu
<script src="module.js"></script>
a następnie użytkownik w pliku js, takim jak
var moduel = require('./module');
Tworzę aplikację za pomocą Electron i działa zgodnie z oczekiwaniami.