JavaScript Hypertext Preprocessor - แรงบันดาลใจจาก PHP ใน JavaScript
เยี่ยมชม JSHP-APP เพื่อดูโครงการสาธิต
อ่านสรุปโดยย่อ ว่าคุณสามารถมีส่วนร่วมในการสนับสนุนได้อย่างไร
>= 11.7.0>= 6.5.0worker_threads ใช้เพื่อเรียกใช้รหัส JSHP หากต้องการเรียกใช้เป็น CLI ที่ใช้งานได้ให้เรียกใช้ npm i -g @aviruk/jshp จากนั้นเรียกใช้ jshp จาก CLI
USAGE: jshp [option] [args]
help Display this message
compile [path] Parse JSHP codes to JS from [path]
compile --verbose [path] List source files
serve [host:port] [path] Serve files from [path]
serve [:port] [path] [host] defauts to 0.0.0.0
version Display version information
ใช้ -ธง --debug เบ็ดด้วย compile หรือ server เพื่อดูร่องรอยสแต็กของการล่มที่เกิดขึ้นระหว่างการดำเนินการ
โปรดทราบว่าธงดีบั๊กมีไว้สำหรับการดีบักแพ็คเกจนี้ มันไม่ได้มีไว้สำหรับการดีบักรหัส JSHP ของคุณ
jshp serve :8080 ~ /Public เพื่อใช้เป็นการพึ่งพาการเรียกใช้ npm i @aviruk/jshp
เมื่อเสร็จแล้วคุณสามารถใช้ไฟล์ JavaScript เพื่อหมุนเซิร์ฟเวอร์โดยใช้ฟังก์ชั่นจากโมดูลตามที่แสดง
ฟังก์ชั่นนี้สามารถนำเข้าโดยสคริปต์อื่น โดยทั่วไปแล้วมันจะล้อมรอบฟังก์ชั่น CLI ที่แท้จริงทำให้สามารถส่งอาร์กิวเมนต์ได้
เป็นผลให้ฟังก์ชั่นนี้ทำงานเหมือน CLI
const jshp = require ( '@aviruk/jshp' ) . jshp ;
/**
* @param {string} option The corresponding CLI option, used 'serve' in this example
* @param {string} hostname Use format 'host:port' or ':port'. Example: localhost:8080.
* @param {string} path The path to server resources
*/
jshp ( 'serve' , ':8080' , '~/Public' ) ; index.jshp.html ในไดเรกทอรีเซิร์ฟเวอร์ของคุณuse strictjshp เพื่อ serve ไดเรกทอรีใช้การเน้นไวยากรณ์ HTML/CSS/JS มาตรฐานและรองรับในโปรแกรมแก้ไขข้อความทั้งหมด ข้อแม้เพียงอย่างเดียวคือการประกาศแท็กที่มีความยาว
หากคุณต้องการเปลี่ยนไฟล์ที่เรียกใช้งานการเปลี่ยนแปลงของคุณคุณจะต้องระบุใน execextensions
<!-- html code -->
< script jshp >
// JS code
</ script >
<!-- more html code -->หรือคุณสามารถใช้สิ่งต่อไปนี้
<!-- html code -->
< ?jshp
// JS code
? >
<!-- more html code -->หรือคุณสามารถใช้สิ่งต่อไปนี้
<!-- html code -->
< ?
// JS code
? >
<!-- more html code -->case-sensitive < body >
< script jshp >
const number = Number ( $_GET [ 'num' ] ) ;
</ script >
< p >
< b > Series: </ b >
< ?
const arr = [];
for (let i = 0; i < number ; i++) {
arr.push(i);
}
echo(String(arr));
? >
</ p >
</ body >ค่าที่ส่งคืนของรหัสภายในบล็อกรหัสที่กำหนดขอบเขตจะปรากฏขึ้นในหน้า
ในระหว่างการแยกวิเคราะห์รหัสภายใน <?( )?> จะได้รับการประเมิน ค่าของรหัสจะปรากฏบนหน้า
แท็กเหล่านี้ควรเป็นที่ต้องการสำหรับการแสดงค่าจากตัวแปรเท่านั้น
< body >
< script jshp >
const NAME = $_GET [ 'name' ] ;
const UID = $_GET [ 'id' ] ;
</ script >
< p > < b > Names: </ b > < ?( NAME )? > </ p >
< p > < b > UID: </ b > < ?( UID.toUpperCase() )? > </ p >
</ body > ในรหัสด้านบน NAME และ UID.toUpperCase() ใช้ภายในแท็กเทมเพลต
ไฟล์ชื่อ config.json ที่วางไว้ที่รูทของทรัพยากรเซิร์ฟเวอร์จะมีการกำหนดค่าสำหรับเซิร์ฟเวอร์
คุณสมบัติใด ๆ ที่ระบุใน config.json จะเขียนทับค่าเริ่มต้นเริ่มต้นอย่างเต็มที่ ดังนั้นหากคุณสมบัติที่จะระบุคืออาร์เรย์ (หรือวัตถุเช่น MatchConfig) ดังนั้นคุณสมบัติทั้งหมดของมันจะต้องระบุไว้ในไฟล์ config.json มิฉะนั้นเซิร์ฟเวอร์อาจผิดพลาด
หากคุณไม่ต้องการเปิดเผย /config.json , /server.log และ /.builds ไดเรกทอรีคุณไม่ควรทำสิ่งนี้
พวกเขามีข้อมูลเกี่ยวกับเซิร์ฟเวอร์รหัสเซิร์ฟเวอร์ของคุณ ฯลฯ และคุณไม่ต้องการเปิดเผย
"forbidden" : [
"/private/.*" ,
"/data/.*" ,
"/assets/.*"
] "forbidden" : [
"/config\.json" , // default
"/server\.log" , // default
"/\.builds/.*" , // default
"/private/.*" ,
"/data/.*" ,
"/assets/.*"
] เซิร์ฟเวอร์สามารถเข้าใจเฉพาะคุณสมบัติต่อไปนี้
หากคุณประกาศคุณสมบัติที่เซิร์ฟเวอร์ไม่เข้าใจมันจะไม่ทำให้เกิดข้อผิดพลาดใด ๆ คุณจะสามารถเข้าถึงคุณสมบัติเหล่านั้นได้จากวัตถุ $_CONFIG ในรหัส JSHP ของคุณ
ส่วนหัวที่ระบุไว้ที่นี่เขียนไว้ในการตอบสนองทุกครั้ง
ค่าเริ่มต้น: "defaultHeaders": {} เช่นวัตถุที่ว่างเปล่า
พา ธ ไปยังไฟล์บันทึกเซิร์ฟเวอร์ การบันทึกสามารถปิดได้โดยการตั้งค่าคุณสมบัติเป็นสตริงเปล่า
[date time] <type> <client-address> <method/response-code> <path>
[2021-12-30@11:26:26] INFO ::1 GET /favicon.ico
[2021-12-30@11:26:26] INFO ::1 200 /favicon.ico
[2021-12-30@11:26:46] INFO ::1 GET /config/
[2021-12-30@11:26:46] INFO ::1 200 /config/index.jshp.html
[2021-12-30@11:27:10] INFO ::1 GET /favicon.ico
[2021-12-30@11:27:10] INFO ::1 200 /favicon.ico
[2021-12-30@11:27:35] INFO ::1 GET /config.json
[2021-12-30@11:27:35] ERROR ::1 403 /config.json
ค่าเริ่มต้น: "logPath": "/server.log"
จำนวนอักขระสูงสุดจากสตริงที่ผ่านที่สามารถพิมพ์โดยฟังก์ชั่น Logger ใน 1 บรรทัด (ดู Functions -> Logger.info(any) )
นอกเหนือจากความยาวนี้ข้อความจะถูกพิมพ์ด้านล่าง
ค่าเริ่มต้น: "inlineLogLength": "96"
พา ธ ไปยังไฟล์ดัชนีหากเส้นทางที่ร้องขอเป็นไดเรกทอรี
ไดเรกทอรีจะต้องจบลงด้วย / ในคำขอ GET มิฉะนั้นจะถูกพิจารณาว่าเป็นไฟล์เว้นแต่ว่า Trailingslashes จะถูกปิดใช้งาน
ถ้า "indexFile": "main.jshp.html" จากนั้นสำหรับคำขอ
GET /msg/ HTTP/1.1
Host: xyz.net
Connection: close
เซิร์ฟเวอร์ให้บริการไฟล์ /msg/main.jshp.html แต่เนื่องจากไฟล์มีส่วนขยาย .jshp.html มันจะถูกดำเนินการ
ค่าเริ่มต้น: "indexFile": "index.jshp.html"
ร้องขอเวลาออก 500 หลังจากจำนวนวินาทีที่ระบุ การหมดเวลานี้กำหนดระยะเวลาที่รหัส JSHP ได้รับอนุญาตให้แยกวิเคราะห์ หากรหัส JSHP มีลูปที่ไม่มีที่สิ้นสุด (หรือคล้ายกัน) มันจะถูกฆ่าหลังจากที่ระบุวินาที
ค่าเริ่มต้น: "timeoutSec": 10
ส่วนขยายของไฟล์ที่ต้องแยกวิเคราะห์สำหรับการเรียกใช้รหัส JSHP
ถ้า "execExtensions": [ ".jshp.html" ] จากนั้นไฟล์ที่ลงท้ายด้วยส่วนขยายเหล่านั้นจะได้รับการแยกวิเคราะห์
ในการแยกวิเคราะห์หากตัวแยกวิเคราะห์พบ JavaScript ที่ปฏิบัติการได้มันจะได้รับการดำเนินการและส่วนที่ไม่สามารถใช้งานได้จะถูกคัดลอก
ค่าเริ่มต้น: "execExtensions": [ ".jshp.html" ]
ต่อท้าย slashes หลังจากไดเรกทอรีไม่จำเป็นถ้าตั้งค่าเป็นเท็จ คุณสมบัตินี้เป็นน้ำตาลวากยสัมพันธ์สำหรับ noextension
ค่าเริ่มต้น: "trailingSlashes": true
หากเส้นทางที่ร้องขอเป็นไฟล์และไม่มีส่วนขยายเซิร์ฟเวอร์จะค้นหาไฟล์ที่มีชื่อที่ร้องขอและหนึ่งในส่วนขยายเหล่านี้
ถ้า "noExtension": [ ".jshp.html" ] จากนั้นสำหรับคำขอ
GET /msg/main HTTP/1.1
Host: xyz.net
Connection: close
เซิร์ฟเวอร์ให้บริการไฟล์ /msg/main.jshp.html นั่นเป็นเพราะ main.jshp.html เป็นไฟล์ที่มีชื่อ main และลงท้ายด้วยและส่วนขยายที่ระบุไว้ใน noExtension แต่เนื่องจากไฟล์มีส่วนขยาย .jshp.html มันจะถูกดำเนินการ
หากส่วนขยายที่ระบุคือ '/' ดังนั้นสำหรับไดเรกทอรี /msg/ , จะไม่จำเป็นต้องใช้สแลชต่อท้าย
ถ้า "noExtension": [ "/", ".jshp.html" ] และ "indexFile": "main.jshp.html"
GET /msg HTTP/1.1
Host: xyz.net
Connection: close
เซิร์ฟเวอร์ให้บริการไฟล์ /msg/main.jshp.html
นี่เป็นเพราะ '/' ถือเป็นส่วนขยาย แต่เส้นทางเป็นไดเรกทอรี สำหรับการทำงานจะต้องระบุไฟล์ดัชนีของไดเรกทอรีใน IndexFile
ค่าเริ่มต้น: "noExtension": [ ".jshp.html" ]
คุณสมบัตินี้ระบุวิธีการจัดการ regexes ในไฟล์กำหนดค่า คุณสมบัติการกำหนดค่าทั้งหมดไม่รองรับ regexes หากคุณสมบัติรองรับ regex มันจะมีคำว่า REGEXSUP ในส่วนของคำอธิบาย
"matchConfig" : {
"matchFromStart" : true ,
"matchTillEnd" : true
} หากค่าเริ่มต้นถูกเก็บไว้สำหรับคุณสมบัติที่รองรับ regex matchFromStart จะเพิ่ม ^ ถึงจุดเริ่มต้นของ Regex และ matchTillEnd จะเพิ่ม $ ให้สิ้นสุด
ถ้า config คือ
"rewrites" : [
{
"req" : "/chat.*" ,
"src" : "/messaging/chat/index.jshp.html"
}
] จากนั้น /chat.* จะถูกเปลี่ยนเป็น regex /^/chat.*/$/ ซึ่งหมายความว่าเส้นทางใด ๆ ที่เริ่มต้นด้วย /chat จะถูกเขียนใหม่ไปยัง src
เรียนรู้เพิ่มเติมเกี่ยวกับเส้นทางการเขียนใหม่ในส่วนการเขียนใหม่
หาก matchTillEnd ถูกปิดใช้งาน /chat.* จะถูกเปลี่ยนเป็น regex /^/chat.*//
เส้นทางสู่ไดเรกทอรีภายใต้รูททรัพยากรที่มีการเก็บรหัสที่รวบรวมไว้
ตรวจสอบให้แน่ใจว่าไดเรกทอรีบิลด์ของคุณอยู่ในรายการที่ถูกห้ามเพื่อป้องกันไม่ให้ลูกค้าอ่านรหัสของคุณ
มิฉะนั้นจะเข้าใจได้อย่างชัดเจนว่าซอร์สโค้ดของคุณจะรั่วไหลออกมา
ค่าเริ่มต้น: "buildDir": "/.builds/",
หาก true ไฟล์ JSHP จะถูกรวบรวมทุกครั้งที่มีการร้องขอไฟล์ เหมาะสำหรับการทดสอบและการดีบัก
ค่าเริ่มต้น: "hotCompile": false
หากเป็น true รหัส JSHP จะถูกรวบรวมเพื่อเรียกใช้งาน JS ในระหว่างการเริ่มต้นเซิร์ฟเวอร์
ค่าเริ่มต้น: "compileOnStart": false
หากมีการร้องขอไฟล์เหล่านี้การตอบสนองคือ 403
หมายเหตุ: คุณสมบัตินี้รองรับ regexes ( REGEXSUP )
"forbidden" : [
"/config\.json" ,
"/server\.log" ,
"/\.builds/.*"
]สำหรับพา ธ ที่ระบุเซิร์ฟเวอร์จะส่งการตอบสนองจากเส้นทางที่ระบุอื่น
ถ้า config คือ
"rewrites" : [
{
"req" : "/chat" ,
"src" : "/messaging/chat/index.jshp.html"
}
]จากนั้นสำหรับการร้องขอ
GET /chat HTTP/1.1
Host: xyz.net
Connection: close
เซิร์ฟเวอร์ให้บริการไฟล์ /messaging/chat/index.jshp.html
มันไม่ใช่การเปลี่ยนเส้นทางดังนั้นมันจะส่งผลให้ 200 ถ้า /messaging/chat/index.jshp.html เป็นเส้นทางคำขอที่ถูกต้อง
หมายเหตุ: คุณสมบัติ req ของคุณสมบัตินี้รองรับ regexes ( REGEXSUP )
ค่าเริ่มต้น: "rewrites": [] เช่นอาร์เรย์ที่ว่างเปล่า
สำหรับพา ธ ที่ระบุเซิร์ฟเวอร์จะส่งการตอบสนอง 3xx ด้วยส่วนหัว Location
ถ้า config คือ
"redirects" : [
{
"req" : "/chat" ,
"src" : "/messaging/chat/index.jshp.html" ,
"status" : 301
}
]จากนั้นสำหรับการร้องขอ
GET /chat HTTP/1.1
Host: xyz.net
Connection: close
เซิร์ฟเวอร์ตอบกลับด้วย
HTTP/1.1 301 Moved Parmanently
Location: /messaging/chat/index.jshp.html
.
.
.
คำขอนี้เป็นการเปลี่ยนเส้นทางดังนั้นจะส่งผลให้ 3xx
ค่าเริ่มต้น: "redirects": [] เช่นอาร์เรย์ที่ว่างเปล่า
หมายเหตุ: คุณสมบัติ req ของคุณสมบัตินี้รองรับ regexes ( REGEXSUP )
หมายเหตุ: เปลี่ยนเส้นทางทำงานสำหรับโดเมนภายนอกเช่นกัน แต่การเปลี่ยนเส้นทางไม่ได้เปิดให้ลูกค้า เซิร์ฟเวอร์เปลี่ยนเส้นทางเฉพาะในกรณีที่คุณระบุใน config.json
หมายเหตุ: หากมีพา ธ ทั้งใน rewrites และ redirects เซิร์ฟเวอร์จะทำการเขียนใหม่
นี่เป็นเพราะคำขอถูกตรวจสอบครั้งแรกสำหรับการเขียนใหม่และจากนั้นสำหรับการเปลี่ยนเส้นทาง
สำหรับข้อผิดพลาด HTTP ที่ระบุไฟล์ที่ระบุจะถูกส่งเป็นการตอบกลับ
ถ้า config คือ
"errFiles" : {
"404" : "/404.jshp.html" ,
"403" : "/403.jshp.html"
} จากนั้นสำหรับข้อผิดพลาด 404 เซิร์ฟเวอร์จะให้บริการไฟล์ /404.jshp.html
หากไม่มีไฟล์ที่ระบุจะมีการส่งการตอบกลับที่ว่างเปล่า
ค่าเริ่มต้น: "errFiles": {} เช่นวัตถุที่ว่างเปล่า
หากเป็น true เซิร์ฟเวอร์จะใช้ response.write เพื่อส่งคำตอบ สำหรับทุก echo เซิร์ฟเวอร์จะทำสิ่งนี้ขึ้นอยู่กับคุณสมบัติ 2 ถัดไป
โดยค่าเริ่มต้นจะถูกเก็บไว้ ด้วยเหตุนี้เซิร์ฟเวอร์จึงรอให้ทั้งหน้าสร้างฝั่งเซิร์ฟเวอร์จากนั้นใช้ response.end เพื่อให้บริการหน้า
setStatusCode() , setHeader() และ setCookie() ก่อนที่คุณจะเขียน HTML หรือสะท้อนบางสิ่งบางอย่าง ค่าเริ่มต้น: "respondInChunks": false
ขีด จำกัด ของตัวละคร / ไบต์เกินกว่าที่ข้อมูลสะท้อนจะแตกเป็นชิ้น ๆ
ค่าเริ่มต้น: "chunkLimit": 200
จำนวนชิ้นส่วนที่จะแยกข้อมูลก้อง
ค่าเริ่มต้น: "chunksPerEcho": 2
คุณสมบัติการกำหนดค่าเหล่านี้ถูกสร้างขึ้นโดยเซิร์ฟเวอร์ในระหว่างการเริ่มต้นและบนเซิร์ฟเวอร์การโทร Server.reloadConfig()
การระบุคุณสมบัติเหล่านี้ใน config.json ไม่มีผลเพราะเซิร์ฟเวอร์จะเขียนทับคุณสมบัติเหล่านี้
โฮสต์เซิร์ฟเวอร์รวบรวมจาก host:port
พอร์ตเซิร์ฟเวอร์รวบรวมจาก host:port
สตริงที่มีพา ธ ไปยังทรัพยากรเซิร์ฟเวอร์ที่รวบรวมจากอาร์กิวเมนต์ path
มันเป็นอาร์เรย์ของเส้นทางทั้งหมดที่จะถูกเขียนใหม่
มันเป็นอาร์เรย์ของเส้นทางทั้งหมดที่จะถูกเปลี่ยนเส้นทาง
มันเป็นแหล่งการแมปวัตถุ (ไฟล์ JSHP) ไปยังไฟล์ที่รวบรวมโดย JavaScript มันถูกสร้างขึ้นเมื่อรวบรวมรหัส JSHP
$_ENV - วัตถุเก็บตัวแปรสภาพแวดล้อมของระบบ$_CONFIG - วัตถุจัดเก็บข้อมูลการกำหนดค่าเซิร์ฟเวอร์$_RES_ROOT - สตริงเก็บพา ธ ไปยังทรัพยากรเซิร์ฟเวอร์$_REQUEST - วัตถุข้อมูลคำขอบางอย่าง$_HEADERS - วัตถุเก็บส่วนหัวของคำขอ$_COOKIES - วัตถุยังไม่ได้ใช้งาน$_GET - วัตถุเก็บพารามิเตอร์ URL$_POST - วัตถุยังไม่ได้ใช้งาน$_SERVER - Object จัดเก็บตัวแปรเซิร์ฟเวอร์บางตัวทำงานระหว่างดำเนินการ$_SESSION - วัตถุยังไม่ได้ใช้งาน response.end() ;jshpnodejsinfox-response-hash อัลกอริทึมคือ md5 โดยค่าเริ่มต้น สำหรับไฟล์ jshp require จะไม่ทำงาน require จะพยายามโหลดโมดูลที่สัมพันธ์กับไดเรกทอรีของปฏิบัติการ ในการโหลดโมดูลที่สัมพันธ์กับรูททรัพยากรเซิร์ฟเวอร์จะมีการ prequire ฟังก์ชั่นพิเศษ
ไวยากรณ์
< script jshp >
const mod = prequire ( 'prebuilt-node-module' ) ;
const mod1 = prequire ( 'js:my-dir/my-module' ) ;
const mod2 = prequire ( '/my-dir/my-module.js' ) ;
const mod3 = prequire ( 'jshp:my-dir/my-jshp-file.jshp.html' ) ;
m1 . foo ( ) ;
m2 . foo ( ) ;
m3 . loadMyContents ( ) ;
</ script > โปรดทราบว่าเส้นทางไปยัง prequire (เริ่มต้นด้วย js: jshp: และ / ) ได้รับการประเมินเทียบกับ $_RES_ROOT
โปรดทราบว่าคำนำหน้า js: คำนำหน้าเป็นทางเลือกสำหรับการโหลดไฟล์ JavaScript
แต่คำนำหน้า jshp: คำนำหน้าเป็นสิ่งจำเป็นอย่างยิ่งหากต้องโหลดไฟล์ jshp อื่น
มิฉะนั้นเซิร์ฟเวอร์จะพยายามเรียกใช้ไฟล์ jshp นั้นเป็น JavaScript และขัดข้องและเบิร์น
โปรดทราบว่าฟังก์ชั่นบางอย่างส่งคืนสัญญา พวกเขาคือ
getStatusCode()Server.reloadConfig()Server.fileCompile(path)Server.recompile() หากไม่มีการจัดการสัญญาที่เหมาะสมคุณอาจได้รับข้อผิดพลาด ขอแนะนำให้คุณใช้คำหลัก await สำหรับรหัสที่ดูสะอาดตา
< script jshp >
echo ( await getStatusCode ( ) ) ; // echoes status code
Message . echo ( JSON . stringify ( // Message.echo doesn't accept Objects
await Server . recompile ( ) , null , 4 ) // echoes the source map data (used by server)
) ;
</ script >หากคุณสงสัยว่าทำไมคุณสามารถใช้การรอคอยได้โดยไม่ต้องสร้างฟังก์ชั่น async อื่นเพื่อบรรจุมันนั่นเป็นเพราะเบื้องหลังรหัส JSHP ทั้งหมดทำงานในฟังก์ชั่น Async
HTTP - nodejs http โมดูลURL - โมดูล url nodejsPATH - โมดูล path NodeJSFS - โมดูล NodeJS fs อ้างถึง GHSA-8R4G-CG4M-X23C
node-static V <= 0.7.11 ได้รับผลกระทบnode-static PR #227%00