JavaScript wymaga () po stronie klienta

84

Czy można używać require()(lub czegoś podobnego) po stronie klienta?

Przykład

var myClass = require('./js/myclass.js');
Debra Maddux
źródło

Odpowiedzi:

41

Należy spojrzeć na require.js lub head.js dla tego produktu.

Andrew Hare
źródło
5
@Debra: Dlaczego nie przejść do sekcji „Użycie” na ich stronie internetowej?
Wyścigi lekkości na orbicie
2
Rzuć okiem na Require () , jeśli potrzebujesz lżejszego rozwiązania niż require.js, head.js lub Lab.js.
Torben
2
... czy w dzisiejszych czasach można pakiet kodu po stronie klienta z mnóstwem narzędzi takich jak WebPack
Aprillion
Podczas korzystania z requirejs zwróć uwagę na zastrzeżenie: stackoverflow.com/questions/29652716/… . W przeciwnym razie działa dla mnie.
user180574
14

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;
Renaat De Muynck
źródło
3
Podobała mi się ta odpowiedź, ponieważ nie jest to rozwiązanie. Naprawdę nienawidzę, kiedy ludzie po prostu dają rozwiązanie. Podaj odpowiedź, która pomoże im znaleźć rozwiązanie następnym razem. Dobra robota!
Jasmine
13

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

serby
źródło
1
Zastanawiam się, czy obecność opcji wartych arkusza kalkulacyjnego oznacza, że ​​jako programiści nie znaleźliśmy jeszcze świetnego sposobu, aby to zrobić?
Costa
7

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/

O co chodzi w systemach modułowych?

xmojmr
źródło
Czy oprócz tworzenia pakietów umożliwia również używanie pakietów węzłów z tego pakietu?
eran otzap
4

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
Andre Backlund
źródło
4

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/

Fernando Mota
źródło
@Dkastner wspomniał już o przeglądarce w 2011 roku. W swojej odpowiedzi
wyszukałem w
2

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.

Mörre
źródło
1

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.

Daniel X Moore
źródło
1

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ć.

Zsolt Szatmari
źródło
0

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:

https://github.com/mckoss/namespace

mckoss
źródło
0

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ł.

Ulad Kasach
źródło
Czy jest gdzieś kompletny przykład roboczy? Próbuję załadować własne zajęcia po stronie klienta i to nie zadziała.
jallmer
-4

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.

manoj
źródło