Co to „wymaga” Javascript?

505

Próbuję uzyskać JavaScript do odczytu / zapisu do bazy danych PostgreSQL. Znalazłem ten projekt na github. Udało mi się uzyskać następujący przykładowy kod do uruchomienia w węźle.

var pg = require('pg'); //native libpq bindings = `var pg = require('pg').native`
var conString = "tcp://postgres:1234@localhost/postgres";

var client = new pg.Client(conString);
client.connect();

//queries are queued and executed one after another once the connection becomes available
client.query("CREATE TEMP TABLE beatles(name varchar(10), height integer, birthday timestamptz)");
client.query("INSERT INTO beatles(name, height, birthday) values($1, $2, $3)", ['Ringo', 67, new Date(1945, 11, 2)]);
client.query("INSERT INTO beatles(name, height, birthday) values($1, $2, $3)", ['John', 68, new Date(1944, 10, 13)]);

//queries can be executed either via text/parameter values passed as individual arguments
//or by passing an options object containing text, (optional) parameter values, and (optional) query name
client.query({
  name: 'insert beatle',
  text: "INSERT INTO beatles(name, height, birthday) values($1, $2, $3)",
  values: ['George', 70, new Date(1946, 02, 14)]
});

//subsequent queries with the same name will be executed without re-parsing the query plan by postgres
client.query({
  name: 'insert beatle',
  values: ['Paul', 63, new Date(1945, 04, 03)]
});
var query = client.query("SELECT * FROM beatles WHERE name = $1", ['John']);

//can stream row results back 1 at a time
query.on('row', function(row) {
  console.log(row);
  console.log("Beatle name: %s", row.name); //Beatle name: John
  console.log("Beatle birth year: %d", row.birthday.getYear()); //dates are returned as javascript dates
  console.log("Beatle height: %d' %d\"", Math.floor(row.height/12), row.height%12); //integers are returned as javascript ints
});

//fired after last row is emitted
query.on('end', function() { 
  client.end();
});

Następnie próbowałem uruchomić go na stronie internetowej, ale nic się nie wydarzyło. Sprawdziłem na konsoli Javascript i po prostu napisałem: „nie określono”.

Czym więc jest to „wymaganie”? Dlaczego działa w węźle, ale nie na stronie internetowej?

Ponadto, zanim udało mi się go uruchomić w węźle, musiałem to zrobić npm install pg. O co chodzi Zajrzałem do katalogu i nie znalazłem pliku pg. Gdzie go położył i jak go JavaScript?

neuromancer
źródło
45
wymagany nie jest częścią javascript, jest słowem kluczowym używanym w nodejs. nodejs nie jest DOM, którego używasz po stronie klienta. więc skrypt, który może współpracować z nodejs, może nie działać w przeglądarce. Czy możesz wywołać okno lub dokument w nodejs? nie, to samo dotyczy wymagania w przeglądarce.
mpm
8
Jak zmienić powyższy kod, aby działał w przeglądarce?
neuromancer
8
Nie możesz rozmawiać z Pg bezpośrednio ze strony internetowej; musisz mieć możliwość otwarcia zwykłego gniazda TCP / IP, przez które możesz wysyłać i odbierać dane binarne, a żadna przeglądarka internetowa na to nie pozwoli. Biblioteka, do której się odwołujesz, jest rozszerzeniem node.js i nie będzie działać w klienckim JavaScript. Zdecydowanie zalecamy rozmowę z serwerem PostgreSQL od klienta za pośrednictwem serwera WWW i żądań / odpowiedzi JSON.
Craig Ringer
1
Korzystam z PostgreSQL lokalnie. Co muszę zainstalować na serwerze WWW?
neuromancer
1
Węzeł? Jest to całkiem dobry serwer WWW, lub może być jednym z nich, do zainstalowania lokalnie.
Timothy Meade

Odpowiedzi:

872

Czym więc jest to „wymaganie”?

require()nie jest częścią standardowego interfejsu API JavaScript. Ale w Node.js jest to wbudowana funkcja specjalnego przeznaczenia: ładowanie modułów .

Moduły są sposobem na podzielenie aplikacji na osobne pliki zamiast posiadania całej aplikacji w jednym pliku. Ta koncepcja występuje również w innych językach z niewielkimi różnicami w składni i zachowaniu, takich jak C include, Python importi tak dalej.

Jedną dużą różnicą między modułami Node.js a JavaScript przeglądarki jest sposób dostępu do kodu jednego skryptu z kodu innego skryptu.

  • W przeglądarce JavaScript skrypty są dodawane za pośrednictwem <script>elementu. Po uruchomieniu wszyscy mają bezpośredni dostęp do zasięgu globalnego, „wspólnej przestrzeni” wszystkich skryptów. Każdy skrypt może dowolnie definiować / modyfikować / usuwać / wywoływać dowolne elementy w zasięgu globalnym.

  • W Node.js każdy moduł ma swój własny zakres. Moduł nie może uzyskać bezpośredniego dostępu do rzeczy zdefiniowanych w innym module, chyba że zdecyduje się je ujawnić. Aby ujawnić rzeczy z modułu, należy je przypisać do exportslub module.exports. Dla modułem dostępu innego modułu exportslub module.exports, należy go używaćrequire() .

W twoim kodzie var pg = require('pg');ładuje pgmoduł, klienta PostgreSQL dla Node.js. Umożliwia to Twojemu kodowi dostęp do funkcjonalności interfejsów API klienta PostgreSQL za pośrednictwem pgzmiennej.

Dlaczego działa w węźle, ale nie na stronie internetowej?

require(), module.exportsI exportssą interfejsy API z systemem moduł, który jest specyficzny dla Node.js. Przeglądarki nie implementują tego systemu modułów.

Ponadto, zanim udało mi się go uruchomić w węźle, musiałem to zrobić npm install pg. O co chodzi

NPM to usługa repozytorium pakietów, która obsługuje opublikowane moduły JavaScript. npm installto polecenie, które pozwala pobierać pakiety z ich repozytorium.

Gdzie go położył i jak go JavaScript?

Npm cli umieszcza wszystkie pobrane moduły w node_moduleskatalogu, w którym działałeś npm install. Node.js ma bardzo szczegółową dokumentację, w jaki sposób moduły znajdują inne moduły, w tym wyszukiwanie node_moduleskatalogu.

Joseph
źródło
13
Myślę, że WebPack ma także własne requirewsparcie ?
Benny Bottema
2
Dlaczego Node.js potrzebuje takiej funkcjonalności?
Melab
23
@Melab Ponieważ modularyzacja jest potrzebna, gdy tylko kod przejdzie do czegoś większego niż ćwiczenie kodowania uniwersyteckiego i zacznie angażować więcej niż 1 osobę. Który jest dlaczego używamy ich, ponieważ, jak, na zawsze .
David Tonhofer,
3
Równowartość w PHP byłoby include/require[_once]( Link php.net ), a nie use, co jest aliasing słów kluczowych.
nevvermind
107

W porządku, zacznijmy więc od rozróżnienia między Javascriptem w przeglądarce a Javascriptem na serwerze (CommonJS i Node).

JavaScript jest językiem tradycyjnie ograniczonym do przeglądarki internetowej z ograniczonym globalnym kontekstem zdefiniowanym głównie przez coś, co stało się tak zwane Document Object Model (DOM) poziom 0 (API JavaScript Netscape Navigator).

Javascript po stronie serwera eliminuje to ograniczenie i pozwala JavaScriptowi wywoływać różne fragmenty natywnego kodu (jak biblioteka Postgres) i otwierać gniazda.

Teraz require()jest specjalne wywołanie funkcji zdefiniowane jako część specyfikacji CommonJS. W węźle rozwiązuje biblioteki i moduły w ścieżce wyszukiwania węzła, teraz zwykle zdefiniowanej jak node_modulesw tym samym katalogu (lub katalogu wywoływanego pliku javascript) lub w ogólnosystemowej ścieżce wyszukiwania.

Aby spróbować odpowiedzieć na resztę pytania, musimy użyć proxy między kodem uruchomionym w przeglądarce a serwerem bazy danych.

Ponieważ dyskutujemy o węźle, a ty już wiesz, jak uruchomić zapytanie z tego miejsca, warto użyć węzła jako tego serwera proxy.

Jako prosty przykład stworzymy adres URL, który zwraca kilka faktów o Beatle, pod nazwą JSON.

/* your connection code */

var express = require('express');
var app = express.createServer();
app.get('/beatles/:name', function(req, res) {
    var name = req.params.name || '';
    name = name.replace(/[^a-zA_Z]/, '');
    if (!name.length) {
        res.send({});
    } else {
        var query = client.query('SELECT * FROM BEATLES WHERE name =\''+name+'\' LIMIT 1');
        var data = {};
        query.on('row', function(row) {
            data = row;
            res.send(data);
        });
    };
});
app.listen(80, '127.0.0.1');
Timothy Meade
źródło
2
jest mylące ... metoda createServerjest myląca ... sugeruje, że mogę po prostu rozmyślnie tworzyć serwery przez cały czas, kiedy tylko chcę ... kontrastować to z moim paradygmatem WAMP: około 5 lat temu zainstalowałem (np. ”) serwer na moim laptopie z systemem WindowsXP, a ja nigdy nie„ stworzyłem ”innego serwera, odkąd… teraz nagle mogę zacząć tworzyć serwery… to mylące…
dsdsdsdsd
a co to jest „express” ... kiedy szukam C:\Program Files\nodejs\ pliku lub katalogu o nazwie express, nie otrzymuję dopasowania ... więc skąd ono pochodzi ...
dsdsdsdsd
1
Express to zbiór oprogramowania pośredniego i frameworka, który ułatwia utworzenie serwera WWW w node.js, musisz go zainstalować npm. Więcej informacji można znaleźć tutaj: expressjs.com
Timothy Meade
To bardzo dobre wytłumaczenie. Mam pytanie czy wymaga pracy z dynamicznymi ścieżkami w środowisku NodeJS i przeglądarce?
M.Abulsoud
29

Służy do ładowania modułów. Użyjmy prostego przykładu.

W pliku circle_object.js:

var Circle = function (radius) {
    this.radius = radius
}
Circle.PI = 3.14

Circle.prototype = {
    area: function () {
        return Circle.PI * this.radius * this.radius;
    }
}

Możemy użyć tego poprzez require:

node> require('circle_object')
{}
node> Circle
{ [Function] PI: 3.14 }
node> var c = new Circle(3)
{ radius: 3 }
node> c.area()

require()Metoda służy do ładowania i cache modułów JavaScript. Jeśli więc chcesz załadować lokalny, względny moduł JavaScript do aplikacji Node.js, możesz po prostu użyćrequire() metody.

Przykład:

var yourModule = require( "your_module_name" ); //.js file extension is optional
Sudhir Bastakoti
źródło
9
Co się stanie, jeśli spróbujesz użyć go na stronie internetowej?
neuromancer
1
Próbuję uzyskać powyższe, aby załadować na stronie internetowej!
neuromancer
7
Czy pierwszy blok kodu powinien znajdować się w pliku o nazwie circle_object.js?
user1416227,
24

Zauważyłem, że podczas gdy inne odpowiedzi wyjaśniły, co jest wymagane i że służy do ładowania modułów w Węźle, nie dały pełnej odpowiedzi na temat ładowania modułów węzła podczas pracy w przeglądarce.

Jest to dość proste do zrobienia. Zainstaluj moduł przy użyciu npm, tak jak to opisano, a sam moduł będzie się znajdować w folderze zwanym zwykle modułami_węzła.

Teraz najprostszym sposobem załadowania go do aplikacji jest odwołanie się do niego z kodu HTML za pomocą znacznika skryptowego wskazującego ten katalog. tzn. jeśli twój katalog node_modules znajduje się w katalogu głównym projektu na tym samym poziomie, co Twój index.html, zapisałbyś to w pliku index.html:

<script src="node_modules/ng"></script>

Cały skrypt zostanie teraz załadowany na stronę - dzięki czemu można uzyskać bezpośredni dostęp do jego zmiennych i metod.

Istnieją inne podejścia, które są szerzej stosowane w większych projektach, takie jak moduł ładujący, taki jak wymagany.js . Z tych dwóch osobiście nie użyłem Require, ale myślę, że wielu ludzi uważa, że ​​to dobra droga.

Sam Redway
źródło
Musisz po prostu przejść do katalogu głównego folderu projektu i wpisać npm install <nazwa modułu>. Na przykład, jeśli wpiszesz npm install bootstrap, zainstaluje bootstrap w katalogu o nazwie node_modules / bootstrap. Możesz teraz załadować bootstrap do aplikacji, jak opisano powyżej. Będziesz musiał mieć zainstalowany węzeł i npm, aby móc z niego oczywiście korzystać. Jeśli potrzebujesz więcej informacji, podaj otrzymany błąd.
Sam Redway,
<name of module>? Oto moja struktura katalogów. Folder główny to xyz. xyz/index.htmlwskazuje na xyz/js/scripts.jsużywanie script tag. xyz/js/scripts.jsma kod require('./module1.js');require('./module2.js');. module1.js/ module2.jssą również w xyz/jsfolderze. Jak teraz scripts.jsudostępnić przeglądarkę?
nadmierna wymiana
16

Wiesz, kiedy uruchamiając JavaScript w przeglądarce, masz dostęp do zmiennych takich jak „window” lub Math? Nie musisz deklarować tych zmiennych, zostały one napisane do użycia w dowolnym momencie.

Cóż, gdy plik jest uruchamiany w środowisku Node.js, istnieje zmienna, której można użyć. Nazywa się to „modułem”. Jest to obiekt. Ma właściwość o nazwie „eksport”. I działa tak:

W pliku, który nazwiemy example.js, piszesz:

przyklad.js

module.exports = "some code";

Teraz chcesz, aby ten ciąg „trochę kodu” w innym pliku.

Nazwiemy inny plik otherFile.js

W tym pliku piszesz:

otherFile.js

let str = require('./example.js')

Ta instrukcja wymaga () trafia do pliku, który umieścisz w niej, znajduje wszystkie dane przechowywane we właściwości module.exports. Część let str = ... oznacza, że ​​wszystko, co wymaga instrukcji, jest przechowywane w zmiennej str.

W tym przykładzie wynikiem końcowym jest to, że w pliku otherFile.js masz teraz:

let string = "jakiś kod";

  • lub -

let str = ('./example.js').module.exports

Uwaga:

nazwa pliku zapisana w instrukcji wymaganej: Jeśli jest to plik lokalny, powinna to być ścieżka do pliku example.js. Ponadto rozszerzenie .js jest dodawane domyślnie, więc nie musiałem go pisać.

Robisz coś podobnego, gdy potrzebujesz bibliotek node.js, takich jak Express. W pliku express.js znajduje się obiekt o nazwie „moduł” z właściwością o nazwie „eksport”.

Wygląda to mniej więcej tak, pod tymi liniami (jestem trochę początkujący, więc niektóre z tych szczegółów mogą nie być dokładne, ale mają na celu przedstawienie koncepcji:

express.js

module.exports = function() {
    //It returns an object with all of the server methods
    return {
        listen: function(port){},
        get: function(route, function(req, res){}){}
     }
}

Jeśli potrzebujesz modułu, wygląda to tak: const modułName = wymagana („nazwa modułu”);

Jeśli potrzebujesz pliku lokalnego, wygląda to tak: const localFile = wymagana ("./ ścieżka / do / plik lokalny");

(zwróć uwagę na ./ na początku nazwy pliku)


Zauważ też, że domyślnie eksport jest obiektem .. np. Module.exports = {} Więc możesz napisać module.exports.myfunction = () => {} przed przypisaniem wartości do module.exports. Ale możesz również zastąpić obiekt, pisząc module.exports = "Nie jestem już obiektem."

Maiya
źródło
6

Dwa smaki modułu. Eksportuje / wymaga:

(patrz tutaj )


Plik eksportu smaku 1 (misc.js):

var x = 5;
var addX = function(value) {
  return value + x;
};
module.exports.x = x;
module.exports.addX = addX;

inny plik:

var misc = require('./misc');
console.log("Adding %d to 10 gives us %d", misc.x, misc.addX(10));


Plik eksportu Flavor 2 (user.js):

var User = function(name, email) {
  this.name = name;
  this.email = email;
};
module.exports = User;

inny plik:

var user = require('./user');
var u = new user();
gryzoń mike
źródło