Javascript นี้ "ต้อง" คืออะไร?


505

ฉันพยายามทำให้ Javascript อ่าน / เขียนไปยังฐานข้อมูล PostgreSQL ฉันพบโครงการนี้ใน GitHub ฉันสามารถรับโค้ดตัวอย่างต่อไปนี้เพื่อทำงานในโหนด

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();
});

ต่อไปฉันพยายามทำให้มันทำงานบนเว็บเพจ แต่ดูเหมือนไม่มีอะไรเกิดขึ้น ฉันตรวจสอบบนคอนโซล Javascript และมันเพิ่งบอกว่า "ไม่จำเป็นต้องกำหนด"

ดังนั้นสิ่งนี้คือ "ต้องการ?" ทำไมมันทำงานในโหนด แต่ไม่ได้อยู่ในหน้าเว็บ?

npm install pgนอกจากนี้ก่อนที่ผมจะได้ไปทำงานในโหนดที่ผมต้องทำ เกี่ยวกับอะไร ฉันค้นหาในไดเรกทอรีและไม่พบไฟล์ pg มันอยู่ตรงไหนและ Javascript หามันได้อย่างไร?


45
ต้องการไม่ใช่ส่วนหนึ่งของจาวาสคริปต์มันเป็นคำหลักที่ใช้ใน nodejs nodejs ไม่ใช่ DOM ที่คุณใช้ฝั่งไคลเอ็นต์ดังนั้นสคริปต์ที่อาจทำงานกับ nodejs อาจไม่ทำงานในเบราว์เซอร์ คุณสามารถเรียกหน้าต่างหรือเอกสารใน nodejs ได้หรือไม่? ไม่เหมือนกันสำหรับเบราว์เซอร์ที่ต้องการ
mpm

8
ฉันจะเปลี่ยนรหัสด้านบนเพื่อให้มันทำงานในเบราว์เซอร์ได้อย่างไร
neuromancer

8
คุณไม่สามารถคุยกับ Pg ได้โดยตรงจากหน้าเว็บ คุณจะต้องสามารถเปิดซ็อกเก็ต tcp / ip ธรรมดาที่คุณสามารถส่งและรับข้อมูลไบนารีผ่านและไม่มีเว็บเบราว์เซอร์ที่จะให้คุณทำเช่นนั้น ไลบรารีที่คุณอ้างถึงเป็นส่วนเสริมสำหรับ node.js และจะไม่ทำงานใน JavaScript ไคลเอ็นต์ ฉันขอแนะนำอย่างยิ่งให้คุณพูดคุยกับเซิร์ฟเวอร์ PostgreSQL ของคุณจากไคลเอนต์ผ่านทางเว็บเซิร์ฟเวอร์และคำขอ JSON / ตอบกลับของคุณ
Craig Ringer

1
ฉันใช้ PostgreSQL ในพื้นที่ ฉันต้องติดตั้งอะไรสำหรับเว็บเซิร์ฟเวอร์
neuromancer

1
โหนด? มันเป็นเว็บเซิร์ฟเวอร์ที่ดีมากหรืออาจเป็นหนึ่งในการติดตั้งในเครื่อง
ทิโมธีมี้ด

คำตอบ:


872

ดังนั้นสิ่งนี้คือ "ต้องการ?"

require()ไม่ได้เป็นส่วนหนึ่งของ API API มาตรฐาน แต่ใน Node.js มันเป็นฟังก์ชั่นในตัวที่มีวัตถุประสงค์พิเศษเพื่อโหลดโมดูลการโหลดโมดูล

โมดูลเป็นวิธีการแยกแอปพลิเคชันออกเป็นไฟล์แยกต่างหากแทนที่จะมีแอปพลิเคชันทั้งหมดของคุณเป็นไฟล์เดียว แนวคิดนี้มีอยู่ในภาษาอื่นที่มีความแตกต่างเล็กน้อยในด้านไวยากรณ์และพฤติกรรมเช่น C's include, Pythonimportและอื่น ๆ

ความแตกต่างที่สำคัญอย่างหนึ่งระหว่างโมดูล Node.js และ JavaScript ของเบราว์เซอร์คือวิธีที่โค้ดของสคริปต์เข้าถึงจากโค้ดของสคริปต์อื่น

  • ในเบราว์เซอร์ JavaScript สคริปต์จะถูกเพิ่มผ่าน<script>องค์ประกอบ เมื่อพวกเขาดำเนินการพวกเขาทุกคนมีการเข้าถึงโดยตรงไปยังขอบเขตทั่วโลกซึ่งเป็น "พื้นที่ที่ใช้ร่วมกัน" ในหมู่สคริปต์ทั้งหมด สคริปต์ใด ๆ สามารถกำหนด / แก้ไข / ลบ / เรียกอะไรบนขอบเขตส่วนกลางได้อย่างอิสระ

  • ใน Node.js แต่ละโมดูลมีขอบเขตของตัวเอง โมดูลไม่สามารถเข้าถึงสิ่งต่าง ๆ ที่กำหนดไว้ในโมดูลอื่นโดยตรงเว้นแต่จะเลือกที่จะเปิดเผยสิ่งเหล่านั้น เผยให้เห็นสิ่งต่าง ๆ จากโมดูลที่พวกเขาจะต้องกำหนดให้หรือexports module.exportsสำหรับโมดูลในการเข้าถึงโมดูลอื่นexportsหรือmodule.exports, มันต้องใช้require()

ในรหัสของคุณvar pg = require('pg');โหลดpgโมดูลไคลเอนต์ PostgreSQL สำหรับ Node.js สิ่งนี้อนุญาตให้โค้ดของคุณเข้าถึงฟังก์ชันการทำงานของ API ของไคลเอนต์ PostgreSQL ผ่านpgตัวแปร

ทำไมมันทำงานในโหนด แต่ไม่ได้อยู่ในหน้าเว็บ?

require(), module.exportsและexportsมี APIs ระบบโมดูลที่เป็นเฉพาะกับ Node.js. เบราว์เซอร์ไม่ได้ใช้ระบบโมดูลนี้

npm install pgนอกจากนี้ก่อนที่ผมจะได้ไปทำงานในโหนดที่ผมต้องทำ เกี่ยวกับอะไร

NPMเป็นบริการพื้นที่เก็บข้อมูลแพคเกจที่โฮสต์โมดูล JavaScript เผยแพร่ npm installเป็นคำสั่งที่ให้คุณดาวน์โหลดแพ็คเกจจากที่เก็บของพวกเขา

มันอยู่ตรงไหนและ Javascript หามันได้อย่างไร?

NPM CLI ทำให้ทุกโมดูลดาวน์โหลดในไดเรกทอรีที่คุณวิ่งnode_modules npm installNode.js มีเอกสารรายละเอียดเกี่ยวกับวิธีที่โมดูลค้นหาโมดูลอื่นซึ่งรวมถึงการค้นหาnode_modulesไดเรกทอรี



2
ทำไม Node.js ต้องการฟังก์ชันนี้
Melab

23
@Melab เนื่องจากการทำให้เป็นโมดูลจำเป็นต้องใช้ทันทีที่รหัสลูกโป่งสำหรับบางสิ่งที่ใหญ่กว่าแบบฝึกหัดการเข้ารหัสของมหาวิทยาลัยและเริ่มมีส่วนร่วมมากกว่า 1 คน ซึ่งเป็นเหตุผลที่เราได้รับใช้พวกเขาตั้งแต่ชอบตลอดไป
David Tonhofer

3
เทียบเท่าใน PHP จะเป็นinclude/require[_once]( ลิงค์ php.net ) ไม่useซึ่งเป็นคำหลักนามแฝง
nevvermind

107

เอาล่ะก่อนอื่นเรามาเริ่มด้วยการแยกความแตกต่างระหว่าง Javascript ในเว็บเบราว์เซอร์และ Javascript บนเซิร์ฟเวอร์ (CommonJS และ Node)

Javascript เป็นภาษาดั้งเดิมที่ถูก จำกัด ไว้ที่เว็บเบราว์เซอร์ที่มีบริบททั่วโลกที่ จำกัด ซึ่งส่วนใหญ่กำหนดโดยสิ่งที่รู้จักกันในนาม Document Object Model (DOM) ระดับ 0 (Netscape Navigator Javascript API)

Javascript ฝั่งเซิร์ฟเวอร์ช่วยกำจัดข้อ จำกัด ดังกล่าวและอนุญาตให้ Javascript โทรไปยังโค้ดเนทีฟต่างๆ (เช่นไลบรารี Postgres) และซ็อกเก็ตเปิด

ตอนนี้require()เป็นการเรียกใช้ฟังก์ชันพิเศษที่กำหนดเป็นส่วนหนึ่งของข้อมูลจำเพาะ CommonJS ในโหนดจะแก้ไขไลบรารีและโมดูลในพา ธ การค้นหาโหนดซึ่งตอนนี้โดยปกติจะกำหนดเป็นnode_modulesในไดเรกทอรีเดียวกัน (หรือไดเรกทอรีของไฟล์จาวาสคริปต์ที่เรียกใช้) หรือเส้นทางการค้นหาทั่วทั้งระบบ

ในการพยายามตอบคำถามที่เหลือของคุณเราต้องใช้พร็อกซีระหว่างรหัสที่ทำงานในเบราว์เซอร์และเซิร์ฟเวอร์ฐานข้อมูล

เนื่องจากเรากำลังพูดคุยเกี่ยวกับโหนดและคุณคุ้นเคยกับวิธีการเรียกใช้แบบสอบถามจากที่นั่นมันจะทำให้รู้สึกถึงการใช้โหนดเป็นพร็อกซีนั้น

ตัวอย่างง่ายๆเราจะสร้าง URL ที่ส่งคืนข้อเท็จจริงบางอย่างเกี่ยวกับ Beatle ที่ได้รับชื่อเป็น 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');

2
มันสับสน ... วิธีcreateServerกำลังสับสน ... มันแสดงให้เห็นว่าฉันสามารถสร้างเซิร์ฟเวอร์ได้ตลอดเวลาเมื่อใดก็ตามที่ฉันต้องการ ... ตรงกันข้ามกับกระบวนทัศน์ WAMP ของฉัน: ประมาณ 5 ปีที่ผ่านมาฉันติดตั้ง (เช่น 'สร้างขึ้น) ') เซิร์ฟเวอร์บนแล็ปท็อป windowsXP ของฉันและฉันไม่เคย' สร้าง 'เซิร์ฟเวอร์อื่นตั้งแต่ ... ตอนนี้ฉันสามารถเริ่มสร้างเซิร์ฟเวอร์ได้ทันที ... มันสับสน ..
dsdsdsdsd

และ 'express' คืออะไร ... เมื่อฉันค้นหาC:\Program Files\nodejs\ ไฟล์หรือไดเรกทอรีที่เรียกว่าexpressฉันไม่ได้รับการจับคู่ ... ดังนั้นมันมาจากที่ไหน ...
dsdsdsdsd

1
Express เป็นคอลเลกชันของมิดเดิ้ลและกรอบการที่ทำให้มันง่ายต่อการสร้างเว็บเซิร์ฟเวอร์ใน Node.js npmคุณจะต้องติดตั้งด้วย คุณสามารถค้นหาข้อมูลเพิ่มเติมได้ที่นี่: expressjs.com
Timothy Meade

นั่นเป็นคำอธิบายที่ดีมาก ฉันมีคำถามต้องใช้งานกับเส้นทางแบบไดนามิกทั้งในสภาพแวดล้อม NodeJS และเบราว์เซอร์?
M.Abulsoud

29

มันใช้ในการโหลดโมดูล ลองใช้ตัวอย่างง่ายๆ

ในไฟล์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;
    }
}

เราสามารถใช้สิ่งนี้ผ่านrequireเช่น:

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

require()วิธีการที่ใช้ในการโหลดและแคช JavaScript โมดูล ดังนั้นหากคุณต้องการโหลดโมดูล JavaScript ที่สัมพันธ์กับโลคัลลงในแอปพลิเคชัน Node.js คุณสามารถใช้require()วิธีนี้ได้

ตัวอย่าง:

var yourModule = require( "your_module_name" ); //.js file extension is optional

9
ถ้าคุณพยายามใช้มันในหน้าเว็บล่ะ
neuromancer

1
ฉันกำลังพยายามที่จะโหลดข้างต้นในหน้าเว็บ!
neuromancer

7
รหัสบล็อกแรกควรอยู่ในไฟล์ชื่อ circle_object.js หรือไม่
user1416227

24

ฉันสังเกตเห็นว่าในขณะที่คำตอบอื่น ๆ อธิบายสิ่งที่จำเป็นต้องมีและมันถูกใช้เพื่อโหลดโมดูลในโหนดพวกเขาไม่ได้ให้การตอบแบบเต็มเกี่ยวกับวิธีการโหลดโมดูลโหนดเมื่อทำงานในเบราว์เซอร์

มันค่อนข้างง่ายที่จะทำ ติดตั้งโมดูลของคุณโดยใช้ npm ตามที่คุณอธิบายและโมดูลเองจะอยู่ในโฟลเดอร์ที่มักเรียกว่า node_modules

ตอนนี้วิธีที่ง่ายที่สุดในการโหลดลงในแอปของคุณคือการอ้างอิงจาก html ของคุณด้วยแท็กสคริปต์ซึ่งชี้ไปที่ไดเรกทอรีนี้ เช่นถ้าไดเรกทอรี node_modules ของคุณอยู่ในรูทของโครงการในระดับเดียวกับ index.html ของคุณคุณจะเขียนสิ่งนี้ใน index.html ของคุณ:

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

สคริปต์ทั้งหมดนั้นจะถูกโหลดเข้าสู่หน้าเว็บเพื่อให้คุณสามารถเข้าถึงตัวแปรและวิธีการได้โดยตรง

มีวิธีการอื่น ๆ ที่มีการใช้กันอย่างแพร่หลายมากขึ้นในโครงการขนาดใหญ่เช่นรถตักดินแบบโมดูลเหมือนrequire.js ของทั้งสองฉันไม่ได้ใช้ต้องการตัวเอง แต่ฉันคิดว่ามันเป็นวิธีที่คนจำนวนมากพิจารณา


คุณเพียงแค่ต้องไปที่รูทของโฟลเดอร์โปรเจ็กต์แล้วพิมพ์ npm install <name of module> ตัวอย่างเช่นถ้าคุณพิมพ์ npm install bootstrap มันจะติดตั้ง bootstrap ในไดเร็กทอรีที่ชื่อว่า node_modules / bootstrap และตอนนี้คุณสามารถโหลด bootstrap ในแอพของคุณตามที่อธิบายไว้ข้างต้น คุณจะต้องติดตั้งโหนดและ npm เพื่อให้สามารถใช้งานได้อย่างชัดเจน หากคุณต้องการข้อมูลเพิ่มเติมโปรดแจ้งข้อผิดพลาดที่คุณได้รับ
Sam Redway

<name of module>? นี่คือโครงสร้างไดเรกทอรีของฉัน โฟลเดอร์รูทคือxyzโฟลเดอร์รากเป็นxyz/index.htmlจุดที่จะต้องใช้xyz/js/scripts.js มีรหัส / ยังอยู่ในโฟลเดอร์ ตอนนี้ฉันจะให้เบราว์เซอร์พร้อมใช้งานได้อย่างไร script tagxyz/js/scripts.jsrequire('./module1.js');require('./module2.js');module1.jsmodule2.jsxyz/jsscripts.js
แลกเปลี่ยน

16

คุณรู้ได้อย่างไรว่าเมื่อคุณใช้งาน JavaScript ในเบราว์เซอร์คุณสามารถเข้าถึงตัวแปรเช่น "window" หรือ Math ได้หรือไม่? คุณไม่จำเป็นต้องประกาศตัวแปรเหล่านี้มันถูกเขียนขึ้นเพื่อให้คุณใช้เมื่อใดก็ตามที่คุณต้องการ

เมื่อคุณเรียกใช้ไฟล์ในสภาพแวดล้อม Node.js จะมีตัวแปรที่คุณสามารถใช้ได้ มันถูกเรียกว่า "โมดูล" มันเป็นวัตถุ มันมีคุณสมบัติที่เรียกว่า "ส่งออก" และใช้งานได้เช่นนี้:

ในไฟล์ที่เราจะตั้งชื่อ example.js คุณเขียน:

example.js

module.exports = "some code";

ตอนนี้คุณต้องการสตริงนี้ "บางรหัส" ในไฟล์อื่น

เราจะตั้งชื่อไฟล์อื่น ๆ ของไฟล์.js

ในไฟล์นี้คุณเขียน:

otherFile.js

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

ที่ต้องการคำสั่ง () ไปที่ไฟล์ที่คุณใส่เข้าไปค้นหาข้อมูลใด ๆ ที่เก็บไว้ในคุณสมบัติ module.exports ส่วนให้ str = ... ของรหัสของคุณหมายความว่าสิ่งที่ต้องการคืนค่าคำสั่งจะถูกเก็บไว้ในตัวแปร str

ดังนั้นในตัวอย่างนี้ผลลัพธ์สุดท้ายคือใน otherFile.js ตอนนี้คุณมีสิ่งนี้:

ให้สตริง = "รหัสบางอย่าง";

  • หรือ -

ให้ str = ('./example.js').module.exports

บันทึก:

ชื่อไฟล์ที่เขียนภายในคำสั่ง require: หากเป็นไฟล์โลคัลควรเป็นไฟล์พา ธ ไปที่ example.js นอกจากนี้ส่วนขยาย. js ถูกเพิ่มโดยค่าเริ่มต้นดังนั้นฉันไม่ต้องเขียนมัน

คุณทำสิ่งที่คล้ายกันเมื่อต้องการไลบรารี node.js เช่น Express ในไฟล์ express.js มีวัตถุชื่อ 'module' พร้อมด้วยคุณสมบัติชื่อ 'exports'

ดังนั้นมันจึงดูเหมือนกับแนวเหล่านี้ภายใต้ประทุน (ฉันค่อนข้างเป็นผู้เริ่มต้นดังนั้นรายละเอียดเหล่านี้บางอย่างอาจไม่แน่นอน แต่เป็นการแสดงแนวคิด:

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){}){}
     }
}

หากคุณต้องการโมดูลดูเหมือนว่า: const moduleName = require ("module-name");

หากคุณต้องการไฟล์โลคัลดูเหมือนว่า: const localFile = require ("./ path / to / local-file");

(สังเกต. ./ ที่จุดเริ่มต้นของชื่อไฟล์)


โปรดทราบว่าโดยค่าเริ่มต้นการส่งออกเป็นวัตถุ .. เช่น module.exports = {} ดังนั้นคุณสามารถเขียน module.exports.myfunction = () => {} ก่อนกำหนดค่าให้กับ module.exports แต่คุณสามารถแทนที่วัตถุด้วยการเขียน module.exports = "ฉันไม่ใช่วัตถุอีกต่อไป"


6

สองรสชาติของโมดูลส่งออก / ต้องการ:

(ดูที่นี่ )


ไฟล์ส่งออกFlavour 1 (misc.js):

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

ไฟล์อื่น ๆ :

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


ไฟล์เอ็กซ์พอร์ตFlavor 2 (user.js):

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

ไฟล์อื่น ๆ :

var user = require('./user');
var u = new user();
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.