หัวเรือ · เห็น · นี · อืม
คำนาม : เวที
- ส่วนของเวทีละครหน้าม่าน
Proscenium ปฏิบัติต่อส่วนหน้าและโค้ดฝั่งไคลเอ็นต์ของคุณในฐานะพลเมืองชั้นหนึ่งของแอป Rails ของคุณ และถือว่าอินเทอร์เน็ต "เร็วตามค่าเริ่มต้น" มันรวมและลดขนาด JavaScript (+ JSX), TypeScript (+TSX) และ CSS แบบเรียลไทม์ ตามความต้องการ และไม่มีการกำหนดค่า
ไฮไลท์:
rails s
!การเริ่มต้นใช้งานนั้นขึ้นอยู่กับว่าคุณกำลังเพิ่ม Proscenium ให้กับแอป Rails ที่มีอยู่หรือสร้างแอปใหม่ ดังนั้นให้เลือกคำแนะนำที่เหมาะสมด้านล่าง:
เพิ่มบรรทัดนี้ลงใน Gemfile ของแอปพลิเคชัน Rails เท่านี้คุณก็พร้อมแล้ว:
gem 'proscenium'
โปรดทราบว่า Proscenium ได้รับการออกแบบมาเพื่อใช้กับ Rails เท่านั้น
ตอนนี้หากคุณเริ่มแอป Rails คุณสามารถเปิดโค้ดส่วนหน้าใดก็ได้ (JS, CSS ฯลฯ) ตัวอย่างเช่น ไฟล์ที่ app/assets/stylesheets/application.css
สามารถเข้าถึงได้ที่ https://localhost:3000/app/assets/stylesheets/application.css
ซึ่งจะถูกรวมกลุ่ม แปลง และย่อขนาด [ในการผลิต] แบบเรียลไทม์
Proscenium เชื่อว่าโค้ดส่วนหน้าของคุณมีความสำคัญพอๆ กับโค้ดแบ็กเอนด์ของคุณ และไม่ได้เป็นสิ่งที่ต้องคิดในภายหลัง - โค้ดเหล่านี้ควรเป็นพลเมืองชั้นหนึ่งของแอป Rails ของคุณ ดังนั้น แทนที่จะต้องโยน JS และ CSS ทั้งหมดของคุณลงในไดเร็กทอรี "app/assets" แล้วต้องใช้กระบวนการแยกต่างหากในการคอมไพล์หรือรวมกลุ่ม เพียงแค่วางไว้ทุกที่ที่คุณต้องการภายในแอปของคุณ แล้วเรียกใช้ Rails!
ตัวอย่างเช่น หากคุณมี JS บางตัวที่จำเป็นสำหรับมุมมอง app/views/users/index.html.erb
เพียงสร้างไฟล์ JS ข้างๆ ที่ app/views/users/index.js
หรือหากคุณมี CSS บางตัวที่แอปพลิเคชันทั้งหมดของคุณใช้ ให้ใส่ไว้ใน app/views/layouts/application.css
และโหลดไว้ข้างๆ เค้าโครงของคุณ บางทีคุณอาจมีฟังก์ชันยูทิลิตี้ JS อยู่บ้าง ดังนั้นให้ใส่ไว้ใน lib/utils.js
เพียงวาง JS(X) และ CSS ของคุณทุกที่ที่คุณต้องการ จากนั้นแอป Rails ของคุณก็จะให้บริการพวกมันจากตำแหน่งที่คุณวางไว้
ใช้ตัวอย่างข้างต้น...
app/views/users/index.js
=> https://localhost:3000/app/views/users/index.js
app/views/layouts/application.css
=> https://localhost:3000/app/views/layouts/application.css
lib/utils.js
=> https://localhost:3000/lib/utils.js
app/components/menu_component.jsx
=> https://localhost:3000/app/components/menu_component.jsx
config/properties.css
=> https://localhost:3000/config/properties.css
Proscenium จะได้รับประสบการณ์ที่ดีที่สุดเมื่อเนื้อหาของคุณถูกโหลดด้านข้างโดยอัตโนมัติ
โดยทั่วไปแล้ว Rails จะโหลดเนื้อหา JavaScript และ CSS ของคุณอย่างเปิดเผยโดยใช้ตัวช่วย javascript_include_tag
และ stylesheet_link_tag
ตัวอย่างเช่น คุณอาจมี CSS "application" ระดับบนสุดอยู่ในไฟล์ที่ /app/assets/stylesheets/application.css
ในทำนองเดียวกัน คุณอาจมี JavaScript ส่วนกลางบางส่วนอยู่ในไฟล์ที่ /app/javascript/application.js
คุณจะต้องรวมไฟล์ทั้งสองนี้ไว้ในเค้าโครงแอปพลิเคชันของคุณด้วยตนเองและประกาศอย่างชัดเจน บางอย่างเช่นนี้:
<%# /app/views/layouts/application.html.erb %>
<!DOCTYPE html >
< html >
< head >
< title > Hello World </ title >
<%= stylesheet_link_tag 'application' %> <!-- << Your app CSS -->
</ head >
< body >
<%= yield %>
<%= javascript_include_tag 'application' %> <!-- << Your app JS -->
</ body >
</ html >
ตอนนี้ คุณอาจมี CSS และ JavaScript บางส่วนที่จำเป็นสำหรับมุมมองเฉพาะและบางส่วนเท่านั้น ดังนั้นคุณจะโหลดสิ่งนั้นในมุมมอง (หรือเลย์เอาต์) ของคุณ ในลักษณะนี้:
<%# /app/views/users/index.html.erb %>
<%= stylesheet_link_tag 'users' %>
<%= javascript_include_tag 'users' %>
<%# needed by the `users/_user.html.erb` partial %>
<%= javascript_include_tag '_user' %>
<% render @users %>
ปัญหาหลักคือคุณต้องติดตามเนื้อหาเหล่านี้ทั้งหมด และตรวจสอบให้แน่ใจว่าแต่ละรายการได้รับการโหลดตามมุมมองทั้งหมดที่ต้องการ แต่ยังหลีกเลี่ยงการโหลดเมื่อไม่จำเป็น นี่อาจเป็นเรื่องเจ็บปวดอย่างยิ่ง โดยเฉพาะอย่างยิ่งเมื่อคุณมียอดดูมากมาย
เมื่อด้านข้างโหลด JavaScript, Typescript และ CSS ด้วย Proscenium พวกมันจะถูกรวมไว้ข้างมุมมอง บางส่วน เลย์เอาต์ และส่วนประกอบของคุณโดยอัตโนมัติ และเมื่อจำเป็นเท่านั้น
การโหลดด้านข้างทำงานโดยการค้นหาไฟล์ JS/TS/CSS ที่มีชื่อเดียวกับมุมมอง บางส่วน เค้าโครง หรือส่วนประกอบของคุณ ตัวอย่างเช่น หากคุณมีมุมมองที่ app/views/users/index.html.erb
Proscenium จะค้นหาไฟล์ JS/TS/CSS ที่ app/views/users/index.js
, app/views/users/index.ts
หรือ app/views/users/index.css
หากพบก็จะรวมไว้ใน HTML สำหรับมุมมองนั้น
JSX ยังรองรับ JavaScript และ Typescript เพียงใช้ส่วนขยาย .jsx
หรือ .tsx
แทน .js
หรือ .ts
เพียงสร้างไฟล์ JS และ/หรือ CSS ที่มีชื่อเดียวกับมุมมอง บางส่วน หรือเค้าโครง
เรามาต่อด้วยตัวอย่างปัญหาของเราด้านบน โดยที่เรามีสินทรัพย์ดังต่อไปนี้
/app/assets/application.css
/app/assets/application.js
/app/assets/users.css
/app/assets/users.js
/app/assets/user.js
เค้าโครงแอปพลิเคชันของคุณอยู่ที่ /app/views/layouts/application.hml.erb
และมุมมองที่ต้องการเนื้อหาผู้ใช้อยู่ที่ /app/views/users/index.html.erb
ดังนั้นให้ย้ายเนื้อหา JS และ CSS ของคุณไปไว้ข้างๆ กัน : :
/app/views/layouts/application.css
/app/views/layouts/application.js
/app/views/users/index.css
/app/views/users/index.js
/app/views/users/_user.js
(บางส่วน) ในเลย์เอาต์และมุมมองของคุณ ให้แทนที่ตัวช่วย javascript_include_tag
และ stylesheet_link_tag
ด้วยตัวช่วย include_asset
จาก Proscenium บางสิ่งเช่นนี้:
<!DOCTYPE html >
< html >
< head >
< title > Hello World </ title >
<%= include_assets # <-- %>
</ head >
< body >
<%= yield %>
</ body >
</ html >
ในคำขอเพจแต่ละหน้า Proscenium จะตรวจสอบว่ามุมมอง เค้าโครง และบางส่วนของคุณมีไฟล์ JS/TS/CSS ที่มีชื่อเดียวกันหรือไม่ จากนั้นจึงรวมไฟล์เหล่านั้นไว้ในที่ใดก็ตามที่คุณวางตัวช่วย include_assets
ตอนนี้คุณไม่จำเป็นต้องจำที่จะรวมเนื้อหาของคุณอีกต่อไป เพียงสร้างมันควบคู่ไปกับมุมมอง บางส่วน และเลย์เอาต์ของคุณ แล้ว Proscenium จะจัดการส่วนที่เหลือเอง
การโหลดด้านข้างถูกเปิดใช้งานตามค่าเริ่มต้น แต่คุณสามารถปิดการใช้งานได้โดยตั้งค่า config.proscenium.side_load
เป็น false
ใน /config/application.rb
นอกจากนี้ยังมีตัวช่วย include_stylesheets
และ include_javascripts
เพื่อให้คุณควบคุมตำแหน่งที่เนื้อหา CSS และ JS จะรวมอยู่ใน HTML ควรใช้ตัวช่วยเหล่านี้แทน include_assets
หากคุณต้องการควบคุมตำแหน่งที่จะรวมเนื้อหาอย่างชัดเจน
การรวมไฟล์หมายถึงการแทรกการอ้างอิงที่นำเข้ามาไว้ในไฟล์นั้นเอง กระบวนการนี้เป็นแบบเรียกซ้ำ ดังนั้นการขึ้นต่อกันของการขึ้นต่อกัน (และอื่นๆ) จะถูกอินไลน์ด้วย
Proscenium จะรวมกลุ่มตามค่าเริ่มต้นและแบบเรียลไทม์ ดังนั้นจึงไม่มีขั้นตอนการสร้างหรือการคอมไพล์ล่วงหน้าแยกต่างหาก
Proscenium รองรับการนำเข้า JS, JSX, TS, TSX, CSS และ SVG จาก NPM, ตาม URL, แอปในเครื่องของคุณ และแม้แต่จาก Ruby Gems อื่นๆ
การนำเข้าทั้งแบบคงที่ ( import
) และไดนามิก ( import()
) ได้รับการสนับสนุนสำหรับ JavaScript และ TypeScript และสามารถใช้เพื่อนำเข้าไฟล์ JS, TS, JSX, TSX, JSON, CSS และ SVG
@import
CSS at-rule รองรับ CSS
ปัจจุบันเส้นทางการนำเข้าจะรวมกลุ่มไว้ก็ต่อเมื่อเป็นสตริงลิเทอรัลหรือรูปแบบ glob เส้นทางการนำเข้ารูปแบบอื่นๆ จะไม่ถูกรวมกลุ่ม และจะถูกเก็บรักษาไว้แบบคำต่อคำในเอาต์พุตที่สร้างขึ้นแทน เนื่องจากการรวมกลุ่มเป็นการดำเนินการในเวลาคอมไพล์ และ Proscenium ไม่สนับสนุนการแก้ไขเส้นทางรันไทม์ทุกรูปแบบ
นี่คือตัวอย่างบางส่วน:
// Analyzable imports (will be bundled)
import "pkg" ;
import ( "pkg" ) ;
import ( `./locale- ${ foo } .json` ) ;
// Non-analyzable imports (will not be bundled)
import ( `pkg/ ${ foo } ` ) ;
วิธีแก้ไขการนำเข้าที่ไม่สามารถวิเคราะห์ได้คือการทำเครื่องหมายแพ็คเกจที่มีโค้ดที่เป็นปัญหานี้ว่าไม่ได้รวมกลุ่มไว้ เพื่อไม่ให้รวมอยู่ในชุดรวม จากนั้นคุณจะต้องตรวจสอบให้แน่ใจว่าสำเนาของแพ็คเกจภายนอกพร้อมใช้งานสำหรับโค้ดที่รวมมาของคุณในขณะรันไทม์
node_modules
) การนำเข้าเปล่า (การนำเข้าที่ไม่ได้ขึ้นต้นด้วย ./
, /
, https://
, http://
) ได้รับการสนับสนุนอย่างสมบูรณ์ และจะใช้ตัวจัดการแพ็คเกจที่คุณเลือก (เช่น NPM, Yarn, pnpm) ผ่านไฟล์ package.json
ที่อยู่ ที่รูทของแอพ Rails ของคุณ
ติดตั้งแพ็คเกจที่คุณต้องการนำเข้าโดยใช้ตัวจัดการแพ็คเกจที่คุณเลือก...
npm install react
... จากนั้นนำเข้าเช่นเดียวกับที่คุณทำกับแพ็คเกจอื่น
import React from "react" ;
และแน่นอน คุณสามารถนำเข้าโค้ดของคุณเองได้ โดยใช้พาธแบบสัมพัทธ์หรือแบบสัมบูรณ์ (นามสกุลไฟล์เป็นทางเลือก และพาธแบบสัมบูรณ์ใช้รูท Rails ของคุณเป็นฐาน):
import utils from "/lib/utils" ;
import constants from "./constants" ;
import Header from "/app/components/header" ;
@import "/lib/reset" ;
บางครั้งคุณไม่ต้องการรวมกลุ่มการนำเข้า ตัวอย่างเช่น คุณต้องการให้แน่ใจว่ามีการโหลด React เพียงอินสแตนซ์เดียวเท่านั้น ในกรณีนี้ คุณสามารถใช้คำนำหน้าการ unbundle
import React from "unbundle:react" ;
ใช้งานได้เฉพาะการนำเข้าแบบเปล่าๆ และแบบท้องถิ่นเท่านั้น
คุณยังสามารถใช้คำนำหน้า unbundle
ในแผนที่นำเข้าของคุณ ซึ่งช่วยให้มั่นใจได้ว่าการนำเข้าเส้นทางใดเส้นทางหนึ่งทั้งหมดจะถูกแยกออกเสมอ:
{
"imports" : {
"react" : " unbundle:react "
}
}
จากนั้นเพียงนำเข้าตามปกติ:
import React from "react" ;
[งานระหว่างดำเนินการ]
รองรับการนำเข้าแผนที่สำหรับทั้ง JS และ CSS ทันที และทำงานได้โดยไม่คำนึงถึงเบราว์เซอร์ที่ใช้งานอยู่ เนื่องจากแผนที่นำเข้าถูกแยกวิเคราะห์และแก้ไขโดย Proscenium บนเซิร์ฟเวอร์ แทนที่จะเป็นโดยเบราว์เซอร์ ซึ่งเร็วกว่าและยังช่วยให้คุณใช้แผนที่นำเข้าในเบราว์เซอร์ที่ยังไม่รองรับได้
หากคุณไม่คุ้นเคยกับแผนที่นำเข้า ให้คิดว่าแผนที่ดังกล่าวเป็นวิธีหนึ่งในการกำหนดนามแฝง
เพียงสร้าง config/import_map.json
และระบุการนำเข้าที่คุณต้องการใช้ ตัวอย่างเช่น:
{
"imports" : {
"react" : " https://esm.sh/[email protected] " ,
"start" : " /lib/start.js " ,
"common" : " /lib/common.css " ,
"@radix-ui/colors/" : " https://esm.sh/@radix-ui/[email protected]/ "
}
}
การใช้แผนที่นำเข้าข้างต้นเราสามารถทำ...
import { useCallback } from "react" ;
import startHere from "start" ;
import styles from "common" ;
และสำหรับ CSS...
@import "common" ;
@import "@radix-ui/colors/blue.css" ;
คุณยังสามารถเขียนแผนที่นำเข้าของคุณใน JavaScript แทน JSON ได้ ดังนั้น แทนที่จะ config/import_map.json
ให้สร้าง config/import_map.js
และกำหนดฟังก์ชันที่ไม่ระบุตัวตน ฟังก์ชันนี้ยอมรับอาร์กิวเมนต์ environment
เดียว
( env ) => ( {
imports : {
react :
env === "development"
? "https://esm.sh/[email protected]?dev"
: "https://esm.sh/[email protected]" ,
} ,
} ) ;
ซอร์สแมปช่วยให้แก้ไขข้อบกพร่องโค้ดของคุณได้ง่ายขึ้น พวกเขาเข้ารหัสข้อมูลที่จำเป็นในการแปลจากออฟเซ็ตบรรทัด/คอลัมน์ในไฟล์เอาต์พุตที่สร้างขึ้นกลับไปเป็นออฟเซ็ตบรรทัด/คอลัมน์ในไฟล์อินพุตต้นฉบับที่เกี่ยวข้อง สิ่งนี้มีประโยชน์หากโค้ดที่คุณสร้างขึ้นแตกต่างจากโค้ดต้นฉบับของคุณเพียงพอ (เช่น โค้ดต้นฉบับของคุณคือ TypeScript หรือคุณเปิดใช้งานการลดขนาด) นอกจากนี้ยังมีประโยชน์หากคุณต้องการดูไฟล์แต่ละไฟล์ในเครื่องมือสำหรับนักพัฒนาซอฟต์แวร์ของเบราว์เซอร์ของคุณ แทนที่จะดูไฟล์รวมขนาดใหญ่เพียงไฟล์เดียว
เอาต์พุตการแมปแหล่งที่มาได้รับการสนับสนุนทั้ง JavaScript และ CSS แต่ละไฟล์จะถูกต่อท้ายด้วยลิงก์ไปยังแผนที่ต้นฉบับ ตัวอย่างเช่น:
//# sourceMappingURL=/app/views/layouts/application.js.map
เครื่องมือพัฒนาเบราว์เซอร์ของคุณควรเลือกสิ่งนี้และโหลดแผนที่ต้นทางโดยอัตโนมัติในเวลาและทุกที่ที่จำเป็น
คุณสามารถนำเข้า SVG จาก JS(X) ซึ่งจะรวมซอร์สโค้ด SVG เข้าด้วยกัน นอกจากนี้ หากนำเข้าจาก JSX หรือ TSX ซอร์สโค้ด SVG จะแสดงผลเป็นส่วนประกอบ JSX/TSX
มีให้ใน
>=0.10.0
คุณสามารถกำหนดและเข้าถึงตัวแปรสภาพแวดล้อมได้จาก JavaScript และ Typescript ของคุณภายใต้เนมสเปซ proscenium.env
เพื่อเหตุผลด้านประสิทธิภาพและความปลอดภัย คุณต้องประกาศชื่อตัวแปรสภาพแวดล้อมที่คุณต้องการเปิดเผยในไฟล์ config/application.rb
config . proscenium . env_vars = Set [ 'API_KEY' , 'SOME_SECRET_VARIABLE' ]
config . proscenium . env_vars << 'ANOTHER_API_KEY'
นี่ถือว่ามีการกำหนดตัวแปรสภาพแวดล้อมที่มีชื่อเดียวกันแล้ว ถ้าไม่ คุณจะต้องกำหนดด้วยตัวเองในโค้ดของคุณโดยใช้วัตถุ ENV
ของ Ruby หรือในเชลล์ของคุณ
ตัวแปรสภาพแวดล้อมที่ประกาศเหล่านี้จะถูกแทนที่ด้วยนิพจน์คงที่ ซึ่งช่วยให้คุณใช้สิ่งนี้ได้ดังนี้:
console . log ( proscenium . env . RAILS_ENV ) ; // console.log("development")
console . log ( proscenium . env . RAILS_ENV === "development" ) ; // console.log(true)
ตัวแปรสภาพแวดล้อม RAILS_ENV
และ NODE_ENV
จะถูกประกาศให้คุณโดยอัตโนมัติเสมอ
นอกจากนี้ Proscenium ยังมีตัวแปร process.env.NODE_ENV
ซึ่งตั้งค่าเป็นค่าเดียวกับ proscenium.env.RAILS_ENV
มีไว้เพื่อสนับสนุนเครื่องมือที่มีอยู่ของชุมชน ซึ่งมักจะอาศัยตัวแปรนี้
ตัวแปรสภาพแวดล้อมมีประสิทธิภาพอย่างยิ่งในการช่วยให้ต้นไม้สั่นไหว
function start ( ) {
console . log ( "start" ) ;
}
function doSomethingDangerous ( ) {
console . log ( "resetDatabase" ) ;
}
proscenium . env . RAILS_ENV === "development" && doSomethingDangerous ( ) ;
start ( ) ;
ในการพัฒนา โค้ดด้านบนจะถูกแปลงเป็นโค้ดต่อไปนี้ โดยละทิ้งคำจำกัดความ และเรียกไปที่ doSomethingDangerous()
function start ( ) {
console . log ( "start" ) ;
}
start ( ) ;
โปรดทราบว่าด้วยเหตุผลด้านความปลอดภัย ตัวแปรสภาพแวดล้อมไม่ได้ถูกแทนที่ในการนำเข้า URL
ตัวแปรสภาพแวดล้อมที่ไม่ได้กำหนดจะถูกแทนที่ด้วย undefined
console . log ( proscenium . env . UNKNOWN ) ; // console.log((void 0).UNKNOWN)
ซึ่งหมายความว่าโค้ดที่อาศัยสิ่งนี้จะไม่ถูกเขย่าแบบทรี คุณสามารถแก้ไขปัญหานี้ได้โดยใช้ตัวดำเนินการ chaining เสริม:
if ( typeof proscenium . env ?. UNKNOWN !== "undefined" ) {
// do something if UNKNOWN is defined
}
มีการสนับสนุนพื้นฐานสำหรับการนำเข้าไฟล์ภาษา Rails ของคุณจาก config/locales/*.yml
โดยส่งออกเป็น JSON
import translations from "@proscenium/i18n" ;
// translations.en.*
ตามค่าเริ่มต้น เอาต์พุตของ Proscenium จะใช้ประโยชน์จากฟีเจอร์ JS สมัยใหม่ทั้งหมดจากข้อมูลจำเพาะ ES2022 และรุ่นก่อนหน้า ตัวอย่างเช่น a !== void 0 && a !== null ? a : b
จะกลายเป็น a ?? b
เมื่อย่อขนาด (เปิดใช้งานโดยค่าเริ่มต้นในการผลิต) ซึ่งใช้ไวยากรณ์จาก JavaScript เวอร์ชัน ES2020 คุณลักษณะไวยากรณ์ใดๆ ที่ ES2020 ไม่รองรับจะถูกแปลงเป็นไวยากรณ์ JavaScript แบบเก่าที่ได้รับการสนับสนุนอย่างกว้างขวางมากขึ้น
การเขย่าต้นไม้เป็นคำที่ชุมชน JavaScript ใช้สำหรับการกำจัดโค้ดที่ไม่ทำงาน ซึ่งเป็นการปรับให้เหมาะสมของคอมไพเลอร์ทั่วไปที่จะลบโค้ดที่ไม่สามารถเข้าถึงได้โดยอัตโนมัติ การเขย่าต้นไม้ถูกเปิดใช้งานตามค่าเริ่มต้นใน Proscenium
function one ( ) {
console . log ( "one" ) ;
}
function two ( ) {
console . log ( "two" ) ;
}
one ( ) ;
โค้ดด้านบนจะถูกแปลงเป็นโค้ดต่อไปนี้ โดยละทิ้ง two()
เนื่องจากไม่เคยถูกเรียก
function one ( ) {
console . log ( "one" ) ;
}
one ( ) ;
มีจำหน่ายใน
>=0.10.0
เนื้อหาที่โหลดด้านข้างจะถูกแยกโค้ดโดยอัตโนมัติ ซึ่งหมายความว่า หากคุณมีไฟล์ที่นำเข้าและใช้นำเข้าหลายครั้ง และด้วยไฟล์ที่แตกต่างกัน ไฟล์นั้นจะถูกแยกออกเป็นไฟล์แยกต่างหาก
เป็นตัวอย่าง:
// /lib/son.js
import father from "./father" ;
father ( ) + " and Son" ;
// /lib/daughter.js
import father from "./father" ;
father ( ) + " and Daughter" ;
// /lib/father.js
export default ( ) => "Father" ;
ทั้ง son.js
และ daughter.js
นำเข้า father.js
ดังนั้นทั้งลูกชายและลูกสาวมักจะรวมสำเนาของ Father ไว้ด้วย ส่งผลให้มีโค้ดที่ซ้ำกันและขนาดบันเดิลที่ใหญ่ขึ้น
หากไฟล์เหล่านี้โหลดแบบไซด์โหลด father.js
จะถูกแยกออกเป็นไฟล์หรือส่วนแยกต่างหาก และดาวน์โหลดเพียงครั้งเดียวเท่านั้น
รหัสที่แชร์ระหว่างจุดเข้าใช้งานหลายจุดจะถูกแยกออกเป็นไฟล์ที่ใช้ร่วมกันแยกต่างหากที่จุดเข้าทั้งสองนำเข้า ด้วยวิธีนี้หากผู้ใช้เรียกดูหน้าหนึ่งก่อนแล้วจึงไปที่หน้าอื่น พวกเขาไม่จำเป็นต้องดาวน์โหลด JavaScript ทั้งหมดสำหรับหน้าที่สองตั้งแต่ต้น หากเบราว์เซอร์ดาวน์โหลดและแคชส่วนที่แชร์ไว้แล้ว
โค้ดที่อ้างอิงผ่านนิพจน์ import()
รนัสจะถูกแยกออกเป็นไฟล์แยกต่างหากและโหลดเมื่อมีการประเมินนิพจน์นั้นเท่านั้น วิธีนี้ช่วยให้คุณปรับปรุงเวลาในการดาวน์โหลดครั้งแรกของแอปได้โดยการดาวน์โหลดเฉพาะโค้ดที่คุณต้องการเมื่อเริ่มต้นระบบ จากนั้นจึงดาวน์โหลดโค้ดเพิ่มเติมอย่างเกียจคร้านหากจำเป็นในภายหลัง
หากไม่มีการแยกโค้ด นิพจน์ import() จะกลายเป็น Promise.resolve().then(() => require())
แทน สิ่งนี้ยังคงรักษาซีแมนทิกส์แบบอะซิงโครนัสของนิพจน์ แต่หมายความว่าโค้ดที่นำเข้าจะรวมอยู่ในบันเดิลเดียวกันแทนที่จะถูกแยกออกเป็นไฟล์แยกต่างหาก
การแยกรหัสถูกเปิดใช้งานตามค่าเริ่มต้น คุณสามารถปิดการใช้งานได้โดยตั้งค่าตัวเลือกการกำหนด code_splitting
เป็น false
ใน /config/application.rb
ของแอปพลิเคชันของคุณ :
config . proscenium . code_splitting = false
มีข้อแม้ที่สำคัญบางประการที่เกี่ยวข้องกับ JavaScript สิ่งเหล่านี้มีรายละเอียดอยู่ในไซต์ esbuild
CSS เป็นประเภทเนื้อหาชั้นหนึ่งใน Proscenium ซึ่งหมายความว่าสามารถรวมไฟล์ CSS ได้โดยตรงโดยไม่จำเป็นต้องนำเข้า CSS ของคุณจากโค้ด JavaScript คุณสามารถ @import
ไฟล์ CSS อื่นๆ และอ้างอิงรูปภาพและไฟล์ฟอนต์ด้วย url()
ได้ และ Proscenium จะรวมทุกอย่างเข้าด้วยกัน
โปรดทราบว่าตามค่าเริ่มต้น ผลลัพธ์ของ Proscenium จะใช้ประโยชน์จากคุณสมบัติ CSS ที่ทันสมัยทั้งหมด ตัวอย่างเช่น color: rgba(255, 0, 0, 0.4)
จะกลายเป็น color: #f006
หลังจากย่อขนาดในการผลิต ซึ่งใช้ไวยากรณ์จาก CSS Color Module ระดับ 4
รองรับไวยากรณ์การซ้อน CSS ใหม่ และแปลงเป็น CSS ที่ไม่ซ้อนกันสำหรับเบราว์เซอร์รุ่นเก่า
Proscenium จะแทรกคำนำหน้าผู้ขายโดยอัตโนมัติเพื่อให้ CSS ของคุณทำงานในเบราว์เซอร์รุ่นเก่าได้
คุณยังสามารถนำเข้า CSS จาก JavaScript ได้อีกด้วย เมื่อคุณทำเช่นนี้ Proscenium จะเพิ่มแต่ละสไตล์ชีตต่อท้ายส่วนหัวของเอกสารเป็นองค์ประกอบ <link>
โดยอัตโนมัติ
import "./button.css" ;
export let Button = ( { text } ) => {
return < div className = "button" > { text } < / div > ;
} ;
Proscenium ใช้ชุดย่อยของโมดูล CSS สนับสนุนคีย์เวิร์ด :local
และ :global
แต่ไม่ใช่คุณสมบัติ composes
(ขอแนะนำให้คุณใช้มิกซ์อินแทน composes
เนื่องจากจะใช้ได้ทุกที่ แม้แต่ในไฟล์ CSS ธรรมดาก็ตาม)
ตั้งชื่อนามสกุล .module.css
ให้ไฟล์ CSS ใดๆ จากนั้น Proscenium จะถือว่าไฟล์นั้นเป็นโมดูล CSS โดยเปลี่ยนชื่อคลาสทั้งหมดด้วยส่วนต่อท้ายเฉพาะของไฟล์
. title {
font-size : 20 em ;
}
อินพุตข้างต้นสร้าง:
. title-5564cdbb {
font-size : 20 em ;
}
ตอนนี้คุณมีชื่อคลาสที่ไม่ซ้ำใครซึ่งคุณสามารถใช้ได้ทุกที่
คุณสามารถอ้างอิงโมดูล CSS จากมุมมอง Rails บางส่วน และเค้าโครงได้โดยใช้ตัวช่วย css_module
ซึ่งยอมรับชื่อคลาสตั้งแต่หนึ่งชื่อขึ้นไป และจะส่งคืนชื่อโมดูล CSS ที่เทียบเท่ากัน - ชื่อคลาสที่มีส่วนต่อท้ายที่ไม่ซ้ำกันต่อท้าย
ด้วยการตั้งค่าการโหลดด้านข้าง คุณสามารถใช้ตัวช่วย css_module
ได้ดังต่อไปนี้
< div >
< h1 class =" <%= css_module :hello_title %> " > Hello World </ h1 >
< p class =" <%= css_module :body , paragraph : %> " >
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
</ p >
</ div >
css_module
ยอมรับชื่อคลาสหลายชื่อ และจะส่งคืนสตริงที่คั่นด้วยช่องว่างของชื่อโมดูล CSS ที่ถูกแปลง
css_module :my_module_name
# => "my_module_name-ABCD1234"
คุณยังสามารถอ้างอิงคลาสจากไฟล์ CSS ใดๆ ก็ได้โดยส่งเส้นทาง URL ไปยังไฟล์ เพื่อเป็นคำนำหน้าชื่อคลาส การทำเช่นนี้จะเป็นการโหลดสไตล์ชีตด้านข้างโดยอัตโนมัติ
css_module '/app/components/button.css@big_button'
# => "big_button"
นอกจากนี้ยังรองรับแพ็คเกจ NPM (ติดตั้งแล้วใน /node_modules):
css_module 'mypackage/button@big_button'
# => "big_button"
css_module
ยังยอมรับอาร์กิวเมนต์คีย์เวิร์ดของ path
ซึ่งช่วยให้คุณระบุเส้นทางไปยังไฟล์ CSS ได้ โปรดทราบว่าสิ่งนี้จะใช้เส้นทางที่กำหนดสำหรับชื่อคลาสทั้งหมดที่ส่งไปยังอินสแตนซ์ของ css_module
นั้น
css_module :my_module_name , path : Rails . root . join ( 'app/components/button.css' )
การนำเข้าโมดูล CSS จาก JS จะเพิ่มสไตล์ชีตต่อท้ายส่วนหัวของเอกสารโดยอัตโนมัติ และผลลัพธ์ของการนำเข้าจะเป็นออบเจ็กต์ของคลาส CSS ไปยังชื่อโมดูล
import styles from "./styles.module.css" ;
// styles == { header: 'header-5564cdbb' }
สิ่งสำคัญคือต้องทราบว่าอ็อบเจ็กต์ที่ส่งออกของชื่อโมดูล CSS จริงๆ แล้วคืออ็อบเจ็กต์ JavaScript Proxy ดังนั้นการทำลายวัตถุจะไม่ทำงาน คุณต้องเข้าถึงคุณสมบัติโดยตรงแทน
นอกจากนี้ การนำเข้าโมดูล CSS ไปยังโมดูล CSS อื่นจะส่งผลให้มีสตริงสรุปเดียวกันสำหรับทุกคลาส
Proscenium มีฟังก์ชันสำหรับการรวมหรือ "ผสม" คลาส CSS เข้ากับคลาสอื่น สิ่งนี้คล้ายกับคุณสมบัติ composes
ของโมดูล CSS แต่ใช้งานได้ทุกที่ และไม่จำกัดเพียงโมดูล CSS
รองรับมิกซ์อิน CSS โดยใช้ @define-mixin
และ @mixin
at-rules
mixin ถูกกำหนดโดยใช้ @define-mixin
at-rule ส่งชื่อซึ่งควรเป็นไปตามความหมายของชื่อคลาส และประกาศกฎของคุณ:
// /lib/mixins.css
@define-mixin bigText {
font-size : 50 px ;
}
ใช้มิกซ์อินโดยใช้ @mixin
at-rule ส่งชื่อของมิกซ์อินที่คุณต้องการใช้ และ URL ที่ประกาศมิกซ์อิน URL ใช้เพื่อแก้ไขมิกซ์อิน และสามารถเป็นแบบสัมพัทธ์ แบบสัมบูรณ์ URL หรือแม้กระทั่งจากแพ็คเกจ NPM
// /app/views/layouts/application.css
p {
@mixin bigText from url ( "/lib/mixins.css" );
color : red;
}
ข้างต้นสร้างผลลัพธ์นี้:
p {
font-size : 50 px ;
color : red;
}
สามารถประกาศ Mixins ในไฟล์ CSS ใดก็ได้ ไม่จำเป็นต้องประกาศในไฟล์เดียวกันกับที่ที่ใช้ อย่างไรก็ตาม หากคุณประกาศและใช้มิกซ์อินในไฟล์เดียวกัน คุณไม่จำเป็นต้องระบุ URL ของตำแหน่งที่ประกาศมิกซ์อิน
@define-mixin bigText {
font-size : 50 px ;
}
p {
@mixin bigText;
color : red;
}
โมดูล CSS และ Mixins ทำงานร่วมกันได้อย่างสมบูรณ์แบบ คุณสามารถรวมมิกซ์อินในโมดูล CSS ได้
มีข้อแม้ที่สำคัญบางประการที่เกี่ยวข้องกับ CSS สิ่งเหล่านี้มีรายละเอียดอยู่ในไซต์ esbuild
Typescript และ TSX ได้รับการสนับสนุนตั้งแต่แกะกล่อง และมีการรองรับในตัวสำหรับการแยกวิเคราะห์ไวยากรณ์ของ TypeScript และละทิ้งคำอธิบายประกอบประเภท เพียงเปลี่ยนชื่อไฟล์ของคุณเป็น .ts
หรือ .tsx
เท่านี้ก็เรียบร้อย
โปรดทราบว่า Proscenium ไม่ได้ทำการตรวจสอบประเภทใดๆ ดังนั้นคุณยังคงจำเป็นต้องเรียกใช้ tsc -noEmit
ควบคู่ไปกับ Proscenium เพื่อตรวจสอบประเภท
มีข้อแม้ที่สำคัญบางประการที่เกี่ยวข้องกับ typescript สิ่งเหล่านี้มีรายละเอียดอยู่ในไซต์ esbuild
โดยทั่วไปการใช้ไวยากรณ์ JSX ต้องการให้คุณนำเข้าไลบรารี JSX ที่คุณใช้ด้วยตนเอง ตัวอย่างเช่น หากคุณใช้ React ตามค่าเริ่มต้น คุณจะต้องนำเข้า React ลงในไฟล์ JSX แต่ละไฟล์ดังนี้:
import * as React from "react" ;
render ( < div / > ) ;
เนื่องจากการแปลง JSX จะเปลี่ยนไวยากรณ์ JSX เป็นการเรียก React.createElement
แต่ไม่ได้นำเข้าอะไรเลย ดังนั้นตัวแปร React จึงไม่ปรากฏโดยอัตโนมัติ
Proscenium สร้างคำสั่งการนำเข้าเหล่านี้ให้กับคุณ โปรดทราบว่าการดำเนินการนี้จะเปลี่ยนวิธีการทำงานของการแปลง JSX โดยสิ้นเชิง ดังนั้นโค้ดของคุณอาจทำให้โค้ดเสียหายหากคุณใช้ไลบรารี JSX ที่ไม่ใช่ React
ในอนาคต [ไม่ไกลเกินไป] คุณจะสามารถกำหนดค่า Proscenium ให้ใช้ไลบรารี JSX อื่น หรือปิดใช้งานการนำเข้าอัตโนมัตินี้ได้อย่างสมบูรณ์
การนำเข้าไฟล์ .json จะแยกวิเคราะห์ไฟล์ JSON ลงในออบเจ็กต์ JavaScript และส่งออกออบเจ็กต์เป็นการส่งออกเริ่มต้น การใช้มันมีลักษณะดังนี้:
import object from "./example.json" ;
console . log ( object ) ;
นอกจากการส่งออกเริ่มต้นแล้ว ยังมีชื่อการส่งออกสำหรับคุณสมบัติระดับบนสุดแต่ละรายการในออบเจ็กต์ JSON การนำเข้าการส่งออกที่มีชื่อโดยตรงหมายความว่า Proscenium สามารถลบส่วนที่ไม่ได้ใช้ของไฟล์ JSON ออกจากบันเดิลได้โดยอัตโนมัติ เหลือเพียงการส่งออกที่มีชื่อที่คุณใช้จริงเท่านั้น ตัวอย่างเช่น รหัสนี้จะรวมเฉพาะช่องเวอร์ชันเมื่อรวมกลุ่มแล้ว:
import { version } from "./package.json" ;
console . log ( version ) ;
Phlex เป็นเฟรมเวิร์กสำหรับการสร้างมุมมองที่รวดเร็ว ใช้ซ้ำได้ และทดสอบได้ใน Ruby ล้วนๆ Proscenium ทำงานได้อย่างสมบูรณ์แบบกับ Phlex โดยรองรับการโหลดด้านข้าง โมดูล CSS และอื่นๆ อีกมากมาย เพียงเขียนคลาส Phlex ของคุณและสืบทอดจาก Proscenium::Phlex
class MyView < Proscenium :: Phlex
def view_template
h1 { 'Hello World' }
end
end
ในเลย์เอาต์ของคุณ ให้รวม Proscenium::Phlex::AssetInclusions
และเรียกตัวช่วย include_assets
class ApplicationLayout < Proscenium :: Phlex
include Proscenium :: Phlex :: AssetInclusions # <--
def view_template ( & )
doctype
html do
head do
title { 'My Awesome App' }
include_assets # <--
end
body ( & )
end
end
end
คุณสามารถรวมเนื้อหา CCS และ JS โดยเฉพาะได้โดยใช้ตัวช่วย include_stylesheets
และ include_javascripts
ซึ่งช่วยให้คุณควบคุมตำแหน่งที่จะรวมไว้ใน HTML ได้
คลาส Phlex ใดๆ ที่สืบทอด Proscenium::Phlex
จะถูกไซด์โหลดโดยอัตโนมัติ
โมดูล CSS ได้รับการรองรับอย่างเต็มที่ในคลาส Phlex พร้อมสิทธิ์เข้าถึงตัวช่วย css_module
หากคุณต้องการ อย่างไรก็ตาม มีวิธีที่ดีกว่าและดูเหมือนไม่มีอีกต่อไปในการอ้างอิงคลาสโมดูล CSS ในคลาส Phlex ของคุณ
ภายในคลาส Phlex ของคุณ ชื่อคลาสใดๆ ที่ขึ้นต้นด้วย @
จะถือเป็นคลาสโมดูล CSS
# /app/views/users/show_view.rb
class Users :: ShowView < Proscenium :: Phlex
def