โปรเจ็กต์นี้บูทด้วย Create React App
ด้านล่างนี้คุณจะพบข้อมูลเกี่ยวกับวิธีการทำงานทั่วไป
คุณสามารถดูคู่มือเวอร์ชันล่าสุดได้ที่นี่
<title>
public
public
.env
<meta>
แบบไดนามิกบนเซิร์ฟเวอร์npm start
ตรวจไม่พบการเปลี่ยนแปลงnpm test
หยุดทำงานบน macOS Sierranpm run build
ออกเร็วเกินไปnpm run build
ล้มเหลวบน Herokunpm run build
ล้มเหลวในการลดขนาดCreate React App แบ่งออกเป็น 2 แพ็คเกจ:
create-react-app
เป็นยูทิลิตีบรรทัดคำสั่งส่วนกลางที่คุณใช้เพื่อสร้างโปรเจ็กต์ใหม่react-scripts
เป็นการพึ่งพาการพัฒนาในโปรเจ็กต์ที่สร้างขึ้น (รวมถึงอันนี้ด้วย) คุณแทบจะไม่ต้องอัปเดต create-react-app
เลย เพราะมันจะมอบหมายการตั้งค่าทั้งหมดให้กับ react-scripts
เมื่อคุณรัน create-react-app
มันจะสร้างโปรเจ็กต์ด้วย react-scripts
เวอร์ชันล่าสุดเสมอ ดังนั้นคุณจะได้รับฟีเจอร์ใหม่ทั้งหมดและการปรับปรุงในแอปที่สร้างขึ้นใหม่โดยอัตโนมัติ
หากต้องการอัปเดตโปรเจ็กต์ที่มีอยู่เป็น react-scripts
เวอร์ชันใหม่ ให้เปิดบันทึกการเปลี่ยนแปลง ค้นหาเวอร์ชันที่คุณกำลังใช้อยู่ (ตรวจสอบ package.json
ในโฟลเดอร์นี้หากคุณไม่แน่ใจ) และใช้คำแนะนำในการย้ายสำหรับเวอร์ชันที่ใหม่กว่า รุ่นต่างๆ
ในกรณีส่วนใหญ่ การกระแทกเวอร์ชัน react-scripts
ใน package.json
และการเรียกใช้ npm install
ในโฟลเดอร์นี้น่าจะเพียงพอแล้ว แต่ควรศึกษาบันทึกการเปลี่ยนแปลงเพื่อดูการเปลี่ยนแปลงที่อาจเกิดขึ้น
เรามุ่งมั่นที่จะรักษาการเปลี่ยนแปลงที่สำคัญให้น้อยที่สุด เพื่อให้คุณสามารถอัปเกรด react-scripts
ได้อย่างไม่ลำบาก
เรายินดีรับฟังความคิดเห็นของคุณเสมอ
หลังจากสร้างแล้ว โครงการของคุณควรมีลักษณะดังนี้:
my-app/
README.md
node_modules/
package.json
public/
index.html
favicon.ico
src/
App.css
App.js
App.test.js
index.css
index.js
logo.svg
สำหรับโปรเจ็กต์ที่จะสร้าง ไฟล์เหล่านี้ต้องมีชื่อไฟล์ตรงกันทุกประการ :
public/index.html
คือเทมเพลตเพจsrc/index.js
คือจุดเริ่มต้น JavaScriptคุณสามารถลบหรือเปลี่ยนชื่อไฟล์อื่นๆ ได้
คุณสามารถสร้างไดเร็กทอรีย่อยภายใน src
ได้ เพื่อให้สร้างใหม่ได้เร็วขึ้น Webpack จะประมวลผลเฉพาะไฟล์ภายใน src
คุณต้อง ใส่ไฟล์ JS และ CSS ลงใน src
ไม่เช่นนั้น Webpack จะไม่เห็นไฟล์เหล่านั้น
เฉพาะไฟล์ที่อยู่ใน public
เท่านั้นที่สามารถใช้ได้จาก public/index.html
อ่านคำแนะนำด้านล่างสำหรับการใช้เนื้อหาจาก JavaScript และ HTML
อย่างไรก็ตาม คุณสามารถสร้างไดเร็กทอรีระดับบนสุดเพิ่มเติมได้
สิ่งเหล่านี้จะไม่รวมอยู่ในรุ่นที่ใช้งานจริง ดังนั้นคุณจึงสามารถใช้สำหรับสิ่งต่าง ๆ เช่น เอกสารประกอบ
ในไดเร็กทอรีโปรเจ็กต์ คุณสามารถรัน:
npm start
เรียกใช้แอปในโหมดการพัฒนา
เปิด http://localhost:3000 เพื่อดูในเบราว์เซอร์
เพจจะโหลดซ้ำหากคุณทำการแก้ไข
คุณจะเห็นข้อผิดพลาดของขุยในคอนโซลด้วย
npm test
เปิดตัวนักวิ่งทดสอบในโหมดนาฬิกาแบบโต้ตอบ
ดูส่วนเกี่ยวกับการรันการทดสอบสำหรับข้อมูลเพิ่มเติม
npm run build
สร้างแอปสำหรับการผลิตไปยัง build
ด์
มันรวม React ในโหมดการผลิตอย่างถูกต้องและปรับโครงสร้างให้เหมาะสมเพื่อประสิทธิภาพที่ดีที่สุด
โครงสร้างถูกย่อให้เล็กลงและชื่อไฟล์มีแฮชด้วย
แอปของคุณพร้อมที่จะปรับใช้แล้ว!
ดูส่วนเกี่ยวกับการปรับใช้สำหรับข้อมูลเพิ่มเติม
npm run eject
หมายเหตุ: นี่เป็นการดำเนินการทางเดียว เมื่อคุณ eject
คุณจะไม่สามารถย้อนกลับไปได้!
หากคุณไม่พอใจกับเครื่องมือสร้างและตัวเลือกการกำหนดค่า คุณสามารถ eject
ได้ตลอดเวลา คำสั่งนี้จะลบการพึ่งพาบิวด์เดียวออกจากโปรเจ็กต์ของคุณ
แต่จะคัดลอกไฟล์การกำหนดค่าทั้งหมดและการพึ่งพาแบบสกรรมกริยา (Webpack, Babel, ESLint ฯลฯ) ลงในโปรเจ็กต์ของคุณเพื่อให้คุณควบคุมไฟล์เหล่านั้นได้อย่างเต็มที่ คำสั่งทั้งหมดยกเว้นคำสั่ง eject
จะยังคงใช้งานได้ แต่จะชี้ไปที่สคริปต์ที่คัดลอกเพื่อให้คุณปรับแต่งได้ ณ จุดนี้คุณต้องอยู่คนเดียว
คุณไม่จำเป็นต้องใช้ eject
เลย ชุดคุณลักษณะที่ได้รับการดูแลจัดการนี้เหมาะสำหรับการปรับใช้ขนาดเล็กและระดับกลาง และคุณไม่ควรรู้สึกว่าจำเป็นต้องใช้คุณลักษณะนี้ อย่างไรก็ตาม เราเข้าใจดีว่าเครื่องมือนี้จะไม่มีประโยชน์หากคุณไม่สามารถปรับแต่งได้เมื่อคุณพร้อม
ตามค่าเริ่มต้น โปรเจ็กต์ที่สร้างขึ้นจะใช้ React เวอร์ชันล่าสุด
คุณสามารถดูเอกสารประกอบ React สำหรับข้อมูลเพิ่มเติมเกี่ยวกับเบราว์เซอร์ที่รองรับ
โปรเจ็กต์นี้รองรับซูเปอร์เซ็ตของมาตรฐาน JavaScript ล่าสุด
นอกจากคุณสมบัติทางไวยากรณ์ ES6 แล้ว ยังรองรับ:
เรียนรู้เพิ่มเติมเกี่ยวกับขั้นตอนข้อเสนอต่างๆ
แม้ว่าเราจะแนะนำให้ใช้ข้อเสนอทดลองด้วยความระมัดระวัง แต่ Facebook ก็ใช้คุณสมบัติเหล่านี้อย่างมากในรหัสผลิตภัณฑ์ ดังนั้นเราจึงตั้งใจที่จะจัดเตรียมโค้ดโมดหากข้อเสนอใด ๆ เหล่านี้มีการเปลี่ยนแปลงในอนาคต
โปรดทราบว่า โปรเจ็กต์มีโพลีฟิล ES6 เพียงไม่กี่ตัวเท่านั้น :
Object.assign()
ผ่าน object-assign
Promise
ผ่าน promise
fetch()
ผ่าน whatwg-fetch
หากคุณใช้คุณสมบัติ ES6+ อื่นๆ ที่ต้องการ การสนับสนุนรันไทม์ (เช่น Array.from()
หรือ Symbol
) ตรวจสอบให้แน่ใจว่าคุณได้รวมโพลีฟิลที่เหมาะสมด้วยตนเอง หรือเบราว์เซอร์ที่คุณกำหนดเป้าหมายรองรับคุณสมบัติเหล่านั้นแล้ว
นอกจากนี้ โปรดทราบว่าการใช้ฟีเจอร์ไวยากรณ์ใหม่ๆ เช่น for...of
หรือ [...nonArrayValue]
ทำให้ Babel ปล่อยโค้ดที่ขึ้นอยู่กับฟีเจอร์รันไทม์ ES6 และอาจไม่ทำงานหากไม่มีโพลีฟิล หากมีข้อสงสัย ให้ใช้ Babel REPL เพื่อดูว่าไวยากรณ์เฉพาะใดที่คอมไพล์ไว้
หากต้องการกำหนดค่าการเน้นไวยากรณ์ในโปรแกรมแก้ไขข้อความที่คุณชื่นชอบ ให้ไปที่หน้าเอกสาร Babel ที่เกี่ยวข้องแล้วทำตามคำแนะนำ บรรณาธิการยอดนิยมบางส่วนได้รับการคุ้มครอง
หมายเหตุ: คุณลักษณะนี้ใช้ได้กับ
[email protected]
และสูงกว่า
นอกจากนี้ยังใช้งานได้กับ npm 3 หรือสูงกว่าเท่านั้น
โปรแกรมแก้ไขบางส่วน รวมถึง Sublime Text, Atom และ Visual Studio Code มีปลั๊กอินสำหรับ ESLint
ไม่จำเป็นสำหรับการขุย คุณควรเห็นเอาต์พุต liner ทั้งในเทอร์มินัลและคอนโซลของเบราว์เซอร์ อย่างไรก็ตาม หากคุณต้องการให้ผลลัพธ์ที่เป็นขุยปรากฏในโปรแกรมแก้ไขของคุณ ก็มีขั้นตอนเพิ่มเติมที่คุณสามารถทำได้
คุณจะต้องติดตั้งปลั๊กอิน ESLint สำหรับโปรแกรมแก้ไขของคุณก่อน จากนั้นเพิ่มไฟล์ชื่อ .eslintrc
ไปที่รูทโปรเจ็กต์:
{
"extends" : "react-app"
}
ตอนนี้บรรณาธิการของคุณควรรายงานคำเตือนที่เป็นขุย
โปรดทราบว่าแม้ว่าคุณจะแก้ไขไฟล์ .eslintrc
เพิ่มเติม การเปลี่ยนแปลงเหล่านี้จะ ส่งผลต่อการรวมตัวแก้ไขเท่านั้น จะไม่ส่งผลกระทบต่อเทอร์มินัลและเอาท์พุตขุยในเบราว์เซอร์ เนื่องจากแอป Create React มีเจตนาให้ชุดกฎขั้นต่ำที่พบข้อผิดพลาดทั่วไป
หากคุณต้องการบังคับใช้สไตล์การเขียนโค้ดสำหรับโปรเจ็กต์ของคุณ ให้ลองใช้ Prettier แทนกฎสไตล์ ESLint
ขณะนี้ฟีเจอร์นี้รองรับเฉพาะ Visual Studio Code และ WebStorm เท่านั้น
Visual Studio Code และ WebStorm รองรับการดีบักทันทีด้วย Create React App สิ่งนี้ช่วยให้คุณในฐานะนักพัฒนาสามารถเขียนและแก้ไขโค้ด React ของคุณได้โดยไม่ต้องออกจากโปรแกรมแก้ไข และที่สำคัญที่สุดคือช่วยให้คุณมีขั้นตอนการพัฒนาอย่างต่อเนื่อง โดยที่การสลับบริบททำได้เพียงเล็กน้อย เนื่องจากคุณไม่จำเป็นต้องสลับระหว่างเครื่องมือต่างๆ
คุณจะต้องติดตั้ง VS Code และ VS Code Chrome Debugger Extension เวอร์ชันล่าสุด
จากนั้นเพิ่มบล็อกด้านล่างลงในไฟล์ launch.json
ของคุณ และวางไว้ภายในโฟลเดอร์ .vscode
ในไดเร็กทอรีรากของแอป
{
"version" : " 0.2.0 " ,
"configurations" : [{
"name" : " Chrome " ,
"type" : " chrome " ,
"request" : " launch " ,
"url" : " http://localhost:3000 " ,
"webRoot" : " ${workspaceRoot}/src " ,
"sourceMapPathOverrides" : {
"webpack:///src/*" : " ${webRoot}/* "
}
}]
}
หมายเหตุ: URL อาจแตกต่างกันหากคุณได้ทำการปรับเปลี่ยนผ่านตัวแปรสภาพแวดล้อม HOST หรือ PORT
เริ่มแอปของคุณด้วยการรัน npm start
และเริ่มการดีบักใน VS Code โดยกด F5
หรือคลิกที่ไอคอนดีบักสีเขียว ตอนนี้คุณสามารถเขียนโค้ด ตั้งค่าเบรกพอยท์ ทำการเปลี่ยนแปลงโค้ด และดีบักโค้ดที่แก้ไขใหม่ ทั้งหมดนี้ทำได้จากโปรแกรมแก้ไขของคุณ
มีปัญหากับ VS Code Debugging ใช่ไหม? โปรดดูคำแนะนำในการแก้ไขปัญหา
คุณจะต้องติดตั้งส่วนขยาย Chrome ที่รองรับ WebStorm และ JetBrains IDE
ในเมนู WebStorm Run
ใช้ เลือก Edit Configurations...
จากนั้นคลิก +
และเลือก JavaScript Debug
วาง http://localhost:3000
ลงในช่อง URL และบันทึกการกำหนดค่า
หมายเหตุ: URL อาจแตกต่างกันหากคุณได้ทำการปรับเปลี่ยนผ่านตัวแปรสภาพแวดล้อม HOST หรือ PORT
เริ่มแอปของคุณโดยเรียกใช้ npm start
จากนั้นกด ^D
บน macOS หรือ F9
บน Windows และ Linux หรือคลิกไอคอนดีบักสีเขียวเพื่อเริ่มการดีบักใน WebStorm
เช่นเดียวกับที่คุณสามารถดีบักแอปพลิเคชันของคุณใน IntelliJ IDEA Ultimate, PhpStorm, PyCharm Pro และ RubyMine
Prettier เป็นตัวจัดรูปแบบโค้ดที่สนับสนุน JavaScript, CSS และ JSON ด้วย Prettier คุณสามารถจัดรูปแบบโค้ดที่คุณเขียนโดยอัตโนมัติเพื่อให้แน่ใจว่าโค้ดมีสไตล์ภายในโปรเจ็กต์ของคุณ ดูหน้า GitHub ของ Prettier สำหรับข้อมูลเพิ่มเติม และดูที่หน้านี้เพื่อดูการทำงานจริง
ในการจัดรูปแบบโค้ดของเราทุกครั้งที่เราคอมมิตใน git เราจำเป็นต้องติดตั้งการขึ้นต่อกันต่อไปนี้:
npm install --save husky lint-staged prettier
หรือคุณสามารถใช้ yarn
:
yarn add husky lint-staged prettier
husky
ทำให้การใช้ githooks เป็นเรื่องง่ายราวกับว่าเป็นสคริปต์ npmlint-staged
ช่วยให้เราสามารถรันสคริปต์บนไฟล์ที่จัดฉากใน git ได้ ดูโพสต์ในบล็อกเกี่ยวกับ Lint-staged เพื่อเรียนรู้เพิ่มเติมprettier
คือฟอร์แมตเตอร์ JavaScript ที่เราจะรันก่อนคอมมิต ตอนนี้เราสามารถตรวจสอบให้แน่ใจว่าทุกไฟล์ได้รับการจัดรูปแบบอย่างถูกต้องโดยเพิ่มสองสามบรรทัดใน package.json
ในรูทโปรเจ็กต์
เพิ่มบรรทัดต่อไปนี้ในส่วน scripts
:
"scripts": {
+ "precommit": "lint-staged",
"start": "react-scripts start",
"build": "react-scripts build",
ต่อไปเราจะเพิ่มฟิลด์ 'lint-staged' ให้กับ package.json
เช่น:
"dependencies": {
// ...
},
+ "lint-staged": {
+ "src/**/*.{js,jsx,json,css}": [
+ "prettier --single-quote --write",
+ "git add"
+ ]
+ },
"scripts": {
ตอนนี้เมื่อใดก็ตามที่คุณกระทำการ Prettier จะจัดรูปแบบไฟล์ที่เปลี่ยนแปลงโดยอัตโนมัติ คุณยังสามารถเรียกใช้ ./node_modules/.bin/prettier --single-quote --write "src/**/*.{js,jsx,json,css}"
เพื่อจัดรูปแบบโปรเจ็กต์ทั้งหมดของคุณเป็นครั้งแรก
ถัดไป คุณอาจต้องการรวม Prettier เข้ากับโปรแกรมแก้ไขที่คุณชื่นชอบ อ่านหัวข้อเกี่ยวกับการบูรณาการตัวแก้ไขในหน้า Prettier GitHub
<title>
คุณสามารถค้นหาไฟล์ HTML ต้นฉบับได้ในโฟลเดอร์ public
ของโปรเจ็กต์ที่สร้างขึ้น คุณสามารถแก้ไขแท็ก <title>
ในนั้นเพื่อเปลี่ยนชื่อจาก "React App" เป็นอย่างอื่นได้
โปรดทราบว่าโดยปกติแล้วคุณจะไม่แก้ไขไฟล์ในโฟลเดอร์ public
บ่อยนัก ตัวอย่างเช่น การเพิ่มสไตล์ชีตทำได้โดยไม่ต้องแตะ HTML
หากคุณต้องการอัปเดตชื่อหน้าแบบไดนามิกตามเนื้อหา คุณสามารถใช้เบราว์เซอร์ document.title
API สำหรับสถานการณ์ที่ซับซ้อนมากขึ้นเมื่อคุณต้องการเปลี่ยนชื่อจากส่วนประกอบ React คุณสามารถใช้ React Helmet ซึ่งเป็นไลบรารีของบุคคลที่สาม
หากคุณใช้เซิร์ฟเวอร์แบบกำหนดเองสำหรับแอปของคุณในการใช้งานจริง และต้องการแก้ไขชื่อก่อนที่จะถูกส่งไปยังเบราว์เซอร์ คุณสามารถทำตามคำแนะนำในส่วนนี้ได้ หรือคุณสามารถสร้างแต่ละหน้าล่วงหน้าเป็นไฟล์ HTML แบบคงที่ จากนั้นจะโหลดชุด JavaScript ซึ่งครอบคลุมอยู่ที่นี่
โครงการที่สร้างขึ้นประกอบด้วย React และ ReactDOM เป็นการพึ่งพา นอกจากนี้ยังมีชุดสคริปต์ที่ใช้โดย Create React App เป็นการพึ่งพาการพัฒนา คุณสามารถติดตั้งการพึ่งพาอื่น ๆ (เช่น React Router) ด้วย npm
:
npm install --save react-router
หรือคุณสามารถใช้ yarn
:
yarn add react-router
สิ่งนี้ใช้ได้กับไลบรารีใด ๆ ไม่ใช่แค่ react-router
การตั้งค่าโปรเจ็กต์นี้รองรับโมดูล ES6 ด้วย Babel
แม้ว่าคุณจะยังคงใช้ require()
และ module.exports
ได้ แต่เราขอแนะนำให้คุณใช้ import
และ export
แทน
ตัวอย่างเช่น:
Button.js
import React , { Component } from 'react' ;
class Button extends Component {
render ( ) {
// ...
}
}
export default Button ; // Don’t forget to use export default!
DangerButton.js
import React , { Component } from 'react' ;
import Button from './Button' ; // Import a component from another file
class DangerButton extends Component {
render ( ) {
return < Button color = "red" /> ;
}
}
export default DangerButton ;
ตระหนักถึงความแตกต่างระหว่างการส่งออกตามค่าเริ่มต้นและที่มีชื่อ มันเป็นสาเหตุของข้อผิดพลาดทั่วไป
เราขอแนะนำให้คุณใช้การนำเข้าและส่งออกเริ่มต้นเมื่อโมดูลส่งออกสิ่งเดียวเท่านั้น (เช่น ส่วนประกอบ) นั่นคือสิ่งที่คุณจะได้รับเมื่อคุณใช้ export default Button
และ import Button from './Button'
การส่งออกที่มีชื่อมีประโยชน์สำหรับโมดูลยูทิลิตี้ที่ส่งออกฟังก์ชันต่างๆ โมดูลอาจมีการส่งออกเริ่มต้นได้มากที่สุดหนึ่งครั้งและมีการส่งออกที่มีชื่อได้มากเท่าที่คุณต้องการ
เรียนรู้เพิ่มเติมเกี่ยวกับโมดูล ES6:
แทนที่จะดาวน์โหลดแอพทั้งหมดก่อนที่ผู้ใช้จะสามารถใช้งานได้ การแยกโค้ดทำให้คุณสามารถแบ่งโค้ดของคุณออกเป็นส่วนเล็กๆ ซึ่งคุณสามารถโหลดได้ตามความต้องการ
การตั้งค่าโปรเจ็กต์นี้รองรับการแยกโค้ดผ่าน import()
ข้อเสนออยู่ในขั้นตอนที่ 3 รูปแบบคล้ายฟังก์ชัน import()
ใช้ชื่อโมดูลเป็นอาร์กิวเมนต์และส่งกลับ Promise
ซึ่งจะแก้ไขวัตถุเนมสเปซของโมดูลเสมอ
นี่คือตัวอย่าง:
moduleA.js
const moduleA = 'Hello' ;
export { moduleA } ;
App.js
import React , { Component } from 'react' ;
class App extends Component {
handleClick = ( ) => {
import ( './moduleA' )
. then ( ( { moduleA } ) => {
// Use moduleA
} )
. catch ( err => {
// Handle failure
} ) ;
} ;
render ( ) {
return (
< div >
< button onClick = { this . handleClick } > Load </ button >
</ div >
) ;
}
}
export default App ;
สิ่งนี้จะทำให้ moduleA.js
และการขึ้นต่อกันที่ไม่ซ้ำกันทั้งหมดเป็นส่วนแยกต่างหากที่จะโหลดหลังจากที่ผู้ใช้คลิกปุ่ม 'โหลด' เท่านั้น
คุณยังสามารถใช้กับไวยากรณ์ async
/ await
ได้หากต้องการ
หากคุณใช้ React Router โปรดดูบทช่วยสอนนี้เกี่ยวกับวิธีใช้การแยกโค้ดด้วย คุณสามารถค้นหาที่เก็บ GitHub ที่แสดงร่วมได้ที่นี่
ตรวจสอบส่วนการแยกรหัสในเอกสาร React
การตั้งค่าโปรเจ็กต์นี้ใช้ Webpack เพื่อจัดการสินทรัพย์ทั้งหมด Webpack นำเสนอวิธีการ "ขยาย" แนวคิด import
ที่กำหนดเองนอกเหนือจาก JavaScript หากต้องการแสดงว่าไฟล์ JavaScript ขึ้นอยู่กับไฟล์ CSS คุณต้อง นำเข้า CSS จากไฟล์ JavaScript :
Button.css
. Button {
padding : 20 px ;
}
Button.js
import React , { Component } from 'react' ;
import './Button.css' ; // Tell Webpack that Button.js uses these styles
class Button extends Component {
render ( ) {
// You can use them as regular CSS styles
return < div className = "Button" /> ;
}
}
สิ่งนี้ไม่จำเป็นสำหรับ React แต่หลายคนพบว่าฟีเจอร์นี้สะดวก คุณสามารถอ่านเกี่ยวกับประโยชน์ของแนวทางนี้ได้ที่นี่ อย่างไรก็ตาม คุณควรทราบว่าสิ่งนี้ทำให้โค้ดของคุณพกพาไปใช้กับเครื่องมือบิลด์และสภาพแวดล้อมอื่นๆ ได้น้อยกว่า Webpack
ในการพัฒนา การแสดงการขึ้นต่อกันด้วยวิธีนี้ทำให้สามารถโหลดสไตล์ของคุณใหม่ได้ทันทีในขณะที่คุณแก้ไข ในการผลิต ไฟล์ CSS ทั้งหมดจะถูกต่อเป็นไฟล์ .css
ที่ย่อขนาดไฟล์เดียวในเอาต์พุตของบิลด์
หากคุณกังวลเกี่ยวกับการใช้ซีแมนทิกส์เฉพาะของ Webpack คุณสามารถใส่ CSS ทั้งหมดของคุณลงใน src/index.css
ได้ มันจะยังคงนำเข้าจาก src/index.js
แต่คุณสามารถลบการนำเข้านั้นออกได้ตลอดเวลาหากคุณย้ายไปยังเครื่องมือสร้างอื่นในภายหลัง
การตั้งค่าโปรเจ็กต์นี้จะย่อขนาด CSS ของคุณและเพิ่มคำนำหน้าผู้ขายโดยอัตโนมัติผ่าน Autoprefixer ดังนั้นคุณจึงไม่ต้องกังวลกับมัน
ตัวอย่างเช่น:
. App {
display : flex;
flex-direction : row;
align-items : center;
}
กลายเป็นสิ่งนี้:
. App {
display : -webkit-box;
display : -ms-flexbox;
display : flex;
-webkit-box-orient : horizontal;
-webkit-box-direction : normal;
-ms-flex-direction : row;
flex-direction : row;
-webkit-box-align : center;
-ms-flex-align : center;
align-items : center;
}
หากคุณต้องการปิดการใช้งานคำนำหน้าอัตโนมัติด้วยเหตุผลบางประการ ให้ทำตามหัวข้อนี้
โดยทั่วไป เราขอแนะนำไม่ให้คุณใช้คลาส CSS เดียวกันซ้ำในคอมโพเนนต์ที่แตกต่างกัน ตัวอย่างเช่น แทนที่จะใช้คลาส CSS .Button
ในคอมโพเนนต์ <AcceptButton>
และ <RejectButton>
เราขอแนะนำให้สร้างคอมโพเนนต์ <Button>
ด้วยสไตล์ .Button
ของตัวเอง ซึ่งทั้ง <AcceptButton>
และ <RejectButton>
สามารถเรนเดอร์ได้ (แต่ไม่ใช่ สืบทอด)
การปฏิบัติตามกฎนี้มักจะทำให้ตัวประมวลผลล่วงหน้า CSS มีประโยชน์น้อยลง เนื่องจากฟีเจอร์ต่างๆ เช่น มิกซ์อินและการซ้อนจะถูกแทนที่ด้วยองค์ประกอบของส่วนประกอบ อย่างไรก็ตาม คุณสามารถรวมตัวประมวลผลล่วงหน้า CSS ได้ หากคุณพบว่ามีประโยชน์ ในคำแนะนำนี้ เราจะใช้ Sass แต่คุณสามารถใช้ Less หรือทางเลือกอื่นก็ได้
ขั้นแรก มาติดตั้งอินเทอร์เฟซบรรทัดคำสั่งสำหรับ Sass:
npm install --save node-sass-chokidar
หรือคุณสามารถใช้ yarn
:
yarn add node-sass-chokidar
จากนั้นใน package.json
ให้เพิ่มบรรทัดต่อไปนี้ใน scripts
:
"scripts": {
+ "build-css": "node-sass-chokidar src/ -o src/",
+ "watch-css": "npm run build-css && node-sass-chokidar src/ -o src/ --watch --recursive",
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test --env=jsdom",
หมายเหตุ: หากต้องการใช้ตัวประมวลผลล่วงหน้าอื่น ให้แทนที่คำสั่ง
build-css
และwatch-css
ตามเอกสารประกอบของตัวประมวลผลล่วงหน้าของคุณ
ตอนนี้คุณสามารถเปลี่ยนชื่อ src/App.css
เป็น src/App.scss
และรัน npm run watch-css
ได้ ผู้เฝ้าดูจะค้นหาไฟล์ Sass ทุกไฟล์ในไดเร็กทอรีย่อย src
และสร้างไฟล์ CSS ที่เกี่ยวข้องถัดจากไฟล์นั้น ในกรณีของเราเขียนทับ src/App.css
เนื่องจาก src/App.js
ยังคงนำเข้า src/App.css
สไตล์จึงกลายเป็นส่วนหนึ่งของแอปพลิเคชันของคุณ ตอนนี้คุณสามารถแก้ไข src/App.scss
และ src/App.css
จะถูกสร้างขึ้นใหม่
หากต้องการแชร์ตัวแปรระหว่างไฟล์ Sass คุณสามารถใช้การนำเข้า Sass ได้ ตัวอย่างเช่น src/App.scss
และไฟล์สไตล์ส่วนประกอบอื่นๆ อาจมี @import "./shared.scss";
ด้วยคำจำกัดความที่แปรผัน
หากต้องการเปิดใช้งานการนำเข้าไฟล์โดยไม่ต้องใช้เส้นทางสัมพัทธ์ คุณสามารถเพิ่มตัวเลือก --include-path
ให้กับคำสั่งใน package.json
"build-css": "node-sass-chokidar --include-path ./src --include-path ./node_modules src/ -o src/",
"watch-css": "npm run build-css && node-sass-chokidar --include-path ./src --include-path ./node_modules src/ -o src/ --watch --recursive",
ซึ่งจะช่วยให้คุณสามารถนำเข้าข้อมูลได้เช่น
@import ' styles/_colors.scss ' ; // assuming a styles directory under src/
@import ' nprogress/nprogress ' ; // importing a css file from the nprogress node module
ณ จุดนี้ คุณอาจต้องการลบไฟล์ CSS ทั้งหมดออกจากตัวควบคุมแหล่งที่มา และเพิ่ม src/**/*.css
ลงในไฟล์ . .gitignore
ของคุณ โดยทั่วไปแล้ว แนวทางปฏิบัติที่ดีคือให้ผลิตภัณฑ์ build อยู่นอกการควบคุมแหล่งที่มา
ในขั้นตอนสุดท้าย คุณอาจพบว่าสะดวกในการรัน watch-css
โดยอัตโนมัติด้วย npm start
และรัน build-css
โดยเป็นส่วนหนึ่งของ npm run build
คุณสามารถใช้ตัวดำเนินการ &&
เพื่อรันสคริปต์สองตัวตามลำดับ อย่างไรก็ตาม ไม่มีวิธีข้ามแพลตฟอร์มในการรันสคริปต์สองตัวพร้อมกัน ดังนั้นเราจะติดตั้งแพ็คเกจสำหรับสิ่งนี้:
npm install --save npm-run-all
หรือคุณสามารถใช้ yarn
:
yarn add npm-run-all
จากนั้นเราสามารถเปลี่ยนสคริปต์ start
และ build
สคริปต์เพื่อรวมคำสั่งตัวประมวลผลล่วงหน้า CSS:
"scripts": {
"build-css": "node-sass-chokidar src/ -o src/",
"watch-css": "npm run build-css && node-sass-chokidar src/ -o src/ --watch --recursive",
- "start": "react-scripts start",
- "build": "react-scripts build",
+ "start-js": "react-scripts start",
+ "start": "npm-run-all -p watch-css start-js",
+ "build-js": "react-scripts build",
+ "build": "npm-run-all build-css build-js",
"test": "react-scripts test --env=jsdom",
"eject": "react-scripts eject"
}
ขณะนี้การรัน npm start
และ npm run build
ยังสร้างไฟล์ Sass ด้วย
ทำไมต้อง node-sass-chokidar
?
node-sass
ได้รับการรายงานว่ามีปัญหาต่อไปนี้:
node-sass --watch
ได้รับการรายงานว่ามี ปัญหาด้านประสิทธิภาพ ในบางเงื่อนไขเมื่อใช้ในเครื่องเสมือนหรือกับนักเทียบท่า
การรวบรวมสไตล์ที่ไม่มีที่สิ้นสุด #1939
node-sass
ได้รับการรายงานว่ามีปัญหาในการตรวจจับไฟล์ใหม่ในไดเร็กทอรี #1891
node-sass-chokidar
ถูกใช้ที่นี่เพื่อแก้ไขปัญหาเหล่านี้
ด้วย Webpack การใช้เนื้อหาคงที่ เช่น รูปภาพและแบบอักษรจะทำงานคล้ายกับ CSS
คุณสามารถ import
ไฟล์ได้ในโมดูล JavaScript สิ่งนี้จะบอก Webpack ให้รวมไฟล์นั้นไว้ในบันเดิล ต่างจากการนำเข้า CSS การนำเข้าไฟล์จะให้ค่าสตริงแก่คุณ ค่านี้เป็นเส้นทางสุดท้ายที่คุณสามารถอ้างอิงในโค้ดของคุณ เช่น เป็นแอตทริบิวต์ src
ของรูปภาพ หรือ href
ของลิงก์ไปยัง PDF
เพื่อลดจำนวนคำขอไปยังเซิร์ฟเวอร์ การนำเข้ารูปภาพที่มีขนาดน้อยกว่า 10,000 ไบต์จะส่งคืน URI ข้อมูลแทนเส้นทาง สิ่งนี้ใช้ได้กับนามสกุลไฟล์ต่อไปนี้: bmp, gif, jpg, jpeg และ png ไฟล์ SVG ถูกแยกออกเนื่องจาก #1153
นี่คือตัวอย่าง:
import React from 'react' ;
import logo from './logo.png' ; // Tell Webpack this JS file uses this image
console . log ( logo ) ; // /logo.84287d09.png
function Header ( ) {
// Import result is the URL of your image
return < img src = { logo } alt = "Logo" /> ;
}
export default Header ;
สิ่งนี้ทำให้แน่ใจได้ว่าเมื่อมีการสร้างโปรเจ็กต์ Webpack จะย้ายอิมเมจไปยังโฟลเดอร์บิลด์อย่างถูกต้อง และให้เส้นทางที่ถูกต้องแก่เรา
สิ่งนี้ใช้ได้กับ CSS เช่นกัน:
. Logo {
background-image : url (. / logo.png);
}
Webpack ค้นหาการอ้างอิงโมดูลที่เกี่ยวข้องทั้งหมดใน CSS (เริ่มต้นด้วย ./
) และแทนที่ด้วยเส้นทางสุดท้ายจากบันเดิลที่คอมไพล์แล้ว หากคุณพิมพ์ผิดหรือลบไฟล์สำคัญโดยไม่ตั้งใจ คุณจะเห็นข้อผิดพลาดในการคอมไพล์ เช่นเดียวกับเมื่อคุณนำเข้าโมดูล JavaScript ที่ไม่มีอยู่จริง ชื่อไฟล์สุดท้ายในชุดที่คอมไพล์แล้วถูกสร้างขึ้นโดย Webpack จากแฮชของเนื้อหา หากเนื้อหาไฟล์มีการเปลี่ยนแปลงในอนาคต Webpack จะตั้งชื่อให้แตกต่างออกไปในการใช้งานจริง ดังนั้นคุณจึงไม่ต้องกังวลกับการแคชเนื้อหาในระยะยาว
โปรดทราบว่านี่เป็นคุณสมบัติที่กำหนดเองของ Webpack ด้วย
ไม่จำเป็นสำหรับ React แต่หลายคนก็ชอบมัน (และ React Native ก็ใช้กลไกที่คล้ายกันสำหรับรูปภาพ)
วิธีอื่นในการจัดการสินทรัพย์คงที่จะอธิบายไว้ในส่วนถัดไป
public
หมายเหตุ: คุณลักษณะนี้ใช้ได้กับ
[email protected]
และสูงกว่า
โฟลเดอร์ public
มีไฟล์ HTML เพื่อให้คุณสามารถปรับแต่งได้ เช่น เพื่อตั้งชื่อหน้า แท็ก <script>
พร้อมโค้ดที่คอมไพล์จะถูกเพิ่มเข้าไปโดยอัตโนมัติในระหว่างกระบวนการสร้าง
คุณยังสามารถเพิ่มเนื้อหาอื่น ๆ ลงในโฟลเดอร์ public
ได้
โปรดทราบว่าโดยปกติแล้วเราขอแนะนำให้คุณ import
เนื้อหาในไฟล์ JavaScript แทน ตัวอย่างเช่น ดูหัวข้อการเพิ่มสไตล์ชีตและการเพิ่มรูปภาพและแบบอักษร กลไกนี้ให้ประโยชน์หลายประการ:
อย่างไรก็ตาม มี ช่องทางหลบหนี ที่คุณสามารถใช้เพื่อเพิ่มเนื้อหานอกระบบโมดูลได้
หากคุณใส่ไฟล์ลงในโฟลเดอร์ public
Webpack จะ ไม่ ประมวลผลไฟล์นั้น แต่จะถูกคัดลอกไปยังโฟลเดอร์ build โดยไม่ถูกแตะต้อง หากต้องการอ้างอิงเนื้อหาในโฟลเดอร์ public
คุณต้องใช้ตัวแปรพิเศษที่เรียกว่า PUBLIC_URL
ภายใน index.html
คุณสามารถใช้ได้ดังนี้:
< link rel =" shortcut icon " href =" %PUBLIC_URL%/favicon.ico " >
เฉพาะไฟล์ที่อยู่ในโฟลเดอร์ public
เท่านั้นที่จะสามารถเข้าถึงได้โดยคำนำหน้า %PUBLIC_URL%
หากคุณต้องการใช้ไฟล์จาก src
หรือ node_modules
คุณจะต้องคัดลอกไฟล์ไปที่นั่นเพื่อระบุความตั้งใจของคุณอย่างชัดเจนในการทำให้ไฟล์นี้เป็นส่วนหนึ่งของบิลด์
เมื่อคุณรัน npm run build
สร้างแอป React จะแทนที่ %PUBLIC_URL%
ด้วยพาธสัมบูรณ์ที่ถูกต้อง ดังนั้นโปรเจ็กต์ของคุณจึงทำงานได้แม้ว่าคุณจะใช้การกำหนดเส้นทางฝั่งไคลเอ็นต์หรือโฮสต์ไว้ที่ URL ที่ไม่ใช่รูท
ในโค้ด JavaScript คุณสามารถใช้ process.env.PUBLIC_URL
เพื่อวัตถุประสงค์ที่คล้ายกัน:
render ( ) {
// Note: this is an escape hatch and should be used sparingly!
// Normally we recommend using `import` for getting asset URLs
// as described in “Adding Images and Fonts” above this section.
return < img src = { process . env . PUBLIC_URL + '/img/logo.png' } /> ;
}
โปรดคำนึงถึงข้อเสียของแนวทางนี้:
public
ที่ได้รับการประมวลผลภายหลังหรือย่อขนาดpublic
โดยปกติเราแนะนำให้นำเข้าสไตล์ชีต รูปภาพ และแบบอักษรจาก JavaScript โฟลเดอร์ public
มีประโยชน์ในการแก้ปัญหาเฉพาะหน้าสำหรับกรณีทั่วไปจำนวนหนึ่ง:
manifest.webmanifest
pace.js
ไว้นอกโค้ดที่รวมมา<script>
โปรดทราบว่าหากคุณเพิ่ม <script>
ที่ประกาศตัวแปรโกลบอล คุณจะต้องอ่านหัวข้อถัดไปเกี่ยวกับการใช้งานตัวแปรเหล่านั้นด้วย
เมื่อคุณรวมสคริปต์ในไฟล์ HTML ที่กำหนดตัวแปรร่วมและพยายามใช้ตัวแปรตัวใดตัวหนึ่งเหล่านี้ในโค้ด linter จะบ่นเนื่องจากไม่สามารถมองเห็นคำจำกัดความของตัวแปรได้
คุณสามารถหลีกเลี่ยงปัญหานี้ได้โดยการอ่านตัวแปรส่วนกลางอย่างชัดเจนจากวัตถุ window
ตัวอย่างเช่น:
const $ = window . $ ;
สิ่งนี้ทำให้ชัดเจนว่าคุณกำลังใช้ตัวแปรส่วนกลางโดยเจตนามากกว่าเพราะการพิมพ์ผิด
หรือคุณสามารถบังคับให้ linter ละเว้นบรรทัดใดๆ ได้โดยการเพิ่ม // eslint-disable-line
หลังจากนั้น
คุณไม่จำเป็นต้องใช้ React Bootstrap ร่วมกับ React แต่เป็นไลบรารียอดนิยมสำหรับการรวม Bootstrap เข้ากับแอป React หากต้องการ คุณสามารถรวมเข้ากับ Create React App ได้โดยทำตามขั้นตอนเหล่านี้:
ติดตั้ง React Bootstrap และ Bootstrap ตั้งแต่ npm React Bootstrap ไม่มี Bootstrap CSS ดังนั้นจึงจำเป็นต้องติดตั้งด้วยเช่นกัน:
npm install --save react-bootstrap bootstrap@3
หรือคุณสามารถใช้ yarn
:
yarn add react-bootstrap bootstrap@3
นำเข้า Bootstrap CSS และอาจเลือก CSS ธีม Bootstrap ในตอนต้นของไฟล์ src/index.js
ของคุณ:
import 'bootstrap/dist/css/bootstrap.css' ;
import 'bootstrap/dist/css/bootstrap-theme.css' ;
// Put any other imports below so that CSS from your
// components takes precedence over default styles.
นำเข้าส่วนประกอบ React Bootstrap ที่จำเป็นภายในไฟล์ src/App.js
หรือไฟล์ส่วนประกอบที่คุณกำหนดเอง:
import { Navbar , Jumbotron , Button } from 'react-bootstrap' ;
ตอนนี้คุณพร้อมที่จะใช้ส่วนประกอบ React Bootstrap ที่นำเข้าภายในลำดับชั้นส่วนประกอบของคุณที่กำหนดไว้ในวิธีการเรนเดอร์ นี่คือตัวอย่าง App.js
ที่ทำซ้ำโดยใช้ React Bootstrap
บางครั้งคุณอาจต้องปรับแต่งสไตล์ภาพของ Bootstrap (หรือแพ็คเกจที่เทียบเท่า)
เราขอแนะนำแนวทางต่อไปนี้:
นี่คือตัวอย่างของการเพิ่ม Bootstrap แบบกำหนดเองที่ทำตามขั้นตอนเหล่านี้
Flow เป็นตัวตรวจสอบประเภทคงที่ที่ช่วยให้คุณเขียนโค้ดที่มีจุดบกพร่องน้อยลง ดูข้อมูลเบื้องต้นเกี่ยวกับการใช้ประเภทคงที่ใน JavaScript หากคุณยังใหม่ต่อแนวคิดนี้
Flow เวอร์ชันล่าสุดใช้งานได้กับโปรเจ็กต์ Create React App ทันที
หากต้องการเพิ่ม Flow ให้กับโปรเจ็กต์ Create React App ให้ทำตามขั้นตอนเหล่านี้:
npm install --save flow-bin
(หรือ yarn add flow-bin
)"flow": "flow"
ลงในส่วน scripts
ของ package.json
ของคุณnpm run flow init
(หรือ yarn flow init
) เพื่อสร้างไฟล์ .flowconfig
ในไดเร็กทอรีราก// @flow
ไปยังไฟล์ใดๆ ที่คุณต้องการพิมพ์ check (เช่น ไปที่ src/App.js
) ตอนนี้คุณสามารถรัน npm run flow
(หรือ yarn flow
) เพื่อตรวจสอบไฟล์เพื่อหาข้อผิดพลาดประเภท คุณสามารถเลือกใช้ IDE เช่น Nuclide เพื่อประสบการณ์การบูรณาการที่ดียิ่งขึ้นได้ ในอนาคตเราวางแผนที่จะรวมเข้ากับ Create React App ให้ใกล้ชิดยิ่งขึ้น
หากต้องการเรียนรู้เพิ่มเติมเกี่ยวกับ Flow โปรดดูเอกสารประกอบ
สร้างแอป React ไม่ได้กำหนดโซลูชันการกำหนดเส้นทางเฉพาะ แต่ React Router เป็นโซลูชันที่ได้รับความนิยมมากที่สุด
หากต้องการเพิ่ม ให้รัน:
npm install --save react-router-dom
หรือคุณสามารถใช้ yarn
:
yarn add react-router-dom
หากต้องการลองใช้ ให้ลบโค้ดทั้งหมดใน src/App.js
แล้วแทนที่ด้วยตัวอย่างใดๆ บนเว็บไซต์ ตัวอย่างพื้นฐานเป็นจุดเริ่มต้นที่ดี
โปรดทราบว่าคุณอาจต้องกำหนดค่าเซิร์ฟเวอร์ที่ใช้งานจริงให้รองรับการกำหนดเส้นทางฝั่งไคลเอ็นต์ก่อนที่จะปรับใช้แอปของคุณ
หมายเหตุ: คุณลักษณะนี้ใช้ได้กับ
[email protected]
และสูงกว่า
โปรเจ็กต์ของคุณสามารถใช้ตัวแปรที่ประกาศในสภาพแวดล้อมของคุณได้เหมือนกับที่ได้รับการประกาศในไฟล์ JS ของคุณภายในเครื่อง ตามค่าเริ่มต้น คุณจะกำหนด NODE_ENV
ให้กับคุณ และตัวแปรสภาพแวดล้อมอื่นๆ ที่ขึ้นต้นด้วย REACT_APP_
ตัวแปรสภาพแวดล้อมจะถูกฝังไว้ในช่วงเวลาที่สร้าง เนื่องจากแอป Create React สร้างชุด HTML/CSS/JS แบบคงที่ จึงไม่สามารถอ่านได้ในขณะรันไทม์ หากต้องการอ่านในขณะรันไทม์ คุณจะต้องโหลด HTML ลงในหน่วยความจำบนเซิร์ฟเวอร์และแทนที่ตัวยึดตำแหน่งในรันไทม์ เช่นเดียวกับที่อธิบายไว้ที่นี่ หรือคุณสามารถสร้างแอปใหม่บนเซิร์ฟเวอร์ได้ทุกเมื่อที่คุณเปลี่ยนแปลง
หมายเหตุ: คุณต้องสร้างตัวแปรสภาพแวดล้อมที่กำหนดเองโดยขึ้นต้นด้วย
REACT_APP_
ตัวแปรอื่นๆ ยกเว้นNODE_ENV
จะถูกละเว้นเพื่อหลีกเลี่ยงการเปิดเผยคีย์ส่วนตัวบนเครื่องที่อาจมีชื่อเดียวกันโดยไม่ได้ตั้งใจ การเปลี่ยนแปลงตัวแปรสภาพแวดล้อมจะทำให้คุณต้องรีสตาร์ทเซิร์ฟเวอร์การพัฒนาหากเซิร์ฟเวอร์กำลังทำงานอยู่
ตัวแปรสภาพแวดล้อมเหล่านี้จะถูกกำหนดให้คุณใน process.env
ตัวอย่างเช่น การมีตัวแปรสภาพแวดล้อมชื่อ REACT_APP_SECRET_CODE
จะถูกเปิดเผยใน JS ของคุณเป็น process.env.REACT_APP_SECRET_CODE
นอกจากนี้ยังมีตัวแปรสภาพแวดล้อมในตัวพิเศษที่เรียกว่า NODE_ENV
คุณสามารถอ่านได้จาก process.env.NODE_ENV
เมื่อคุณรัน npm start
มันจะเท่ากับ 'development'
เสมอ เมื่อคุณรัน npm test
มันจะเท่ากับ 'test'
เสมอ และเมื่อคุณรัน npm run build
เพื่อสร้างบันเดิลที่ใช้งานจริง มันจะเท่ากับ 'production'
เสมอ . คุณไม่สามารถแทนที่ NODE_ENV
ด้วยตนเองได้ สิ่งนี้จะป้องกันไม่ให้นักพัฒนาปรับใช้รุ่นการพัฒนาที่ช้าไปสู่การใช้งานจริงโดยไม่ตั้งใจ
ตัวแปรสภาพแวดล้อมเหล่านี้มีประโยชน์สำหรับการแสดงข้อมูลตามเงื่อนไขโดยอิงจากตำแหน่งที่มีการปรับใช้โปรเจ็กต์หรือใช้ข้อมูลที่ละเอียดอ่อนซึ่งอยู่นอกการควบคุมเวอร์ชัน
ขั้นแรก คุณต้องมีการกำหนดตัวแปรสภาพแวดล้อม ตัวอย่างเช่น สมมติว่าคุณต้องการใช้ความลับที่กำหนดไว้ในสภาพแวดล้อมภายใน <form>
:
render ( ) {
return (
< div >
< small > You are running this application in < b > { process . env . NODE_ENV } </ b > mode. </ small >
< form >
< input type = "hidden" defaultValue = { process . env . REACT_APP_SECRET_CODE } />
</ form >
</ div >
) ;
}
ในระหว่างการสร้าง process.env.REACT_APP_SECRET_CODE
จะถูกแทนที่ด้วยค่าปัจจุบันของตัวแปรสภาพแวดล้อม REACT_APP_SECRET_CODE
โปรดจำไว้ว่าตัวแปร NODE_ENV
จะถูกตั้งค่าให้คุณโดยอัตโนมัติ
เมื่อคุณโหลดแอปในเบราว์เซอร์และตรวจสอบ <input>
คุณจะเห็นค่าที่ตั้งเป็น abcdef
และข้อความตัวหนาจะแสดงสภาพแวดล้อมที่ให้ไว้เมื่อใช้ npm start
:
< div >
< small > You are running this application in < b > development </ b > mode. </ small >
< form >
< input type =" hidden " value =" abcdef " />
</ form >
</ div >
แบบฟอร์มด้านบนกำลังมองหาตัวแปรที่เรียกว่า REACT_APP_SECRET_CODE
จากสภาพแวดล้อม เพื่อที่จะใช้ค่านี้ เราจำเป็นต้องกำหนดไว้ในสภาพแวดล้อม ซึ่งสามารถทำได้สองวิธี: ในเชลล์ของคุณหรือในไฟล์ . .env
ทั้งสองวิธีนี้จะอธิบายไว้ในหัวข้อถัดไป
การเข้าถึง NODE_ENV
ยังมีประโยชน์สำหรับการดำเนินการตามเงื่อนไข:
if ( process . env . NODE_ENV !== 'production' ) {
analytics . disable ( ) ;
}
เมื่อคุณคอมไพล์แอปด้วย npm run build
ขั้นตอนการย่อขนาดจะตัดเงื่อนไขนี้ออก และบันเดิลผลลัพธ์จะมีขนาดเล็กลง
หมายเหตุ: คุณลักษณะนี้ใช้ได้กับ
[email protected]
และสูงกว่า
คุณยังสามารถเข้าถึงตัวแปรสภาพแวดล้อมที่เริ่มต้นด้วย REACT_APP_
ใน public/index.html
ตัวอย่างเช่น:
< title > %REACT_APP_WEBSITE_NAME% </ title >
โปรดทราบว่าคำเตือนจากส่วนด้านบนมีผล:
NODE_ENV
และ PUBLIC_URL
) ชื่อตัวแปรต้องขึ้นต้นด้วย REACT_APP_
จึงจะทำงานได้การกำหนดตัวแปรสภาพแวดล้อมอาจแตกต่างกันไปตามระบบปฏิบัติการ สิ่งสำคัญคือต้องทราบด้วยว่าลักษณะนี้เกิดขึ้นชั่วคราวตลอดอายุของเซสชันเชลล์
set " REACT_APP_SECRET_CODE = abcdef " && npm start
(หมายเหตุ: ต้องใช้เครื่องหมายคำพูดล้อมรอบการกำหนดตัวแปรเพื่อหลีกเลี่ยงช่องว่างต่อท้าย)
( $ env: REACT_APP_SECRET_CODE = " abcdef " ) -and (npm start)
REACT_APP_SECRET_CODE=abcdef npm start
.env
หมายเหตุ: คุณลักษณะนี้ใช้ได้กับ
[email protected]
และสูงกว่า
หากต้องการกำหนดตัวแปรสภาพแวดล้อมถาวร ให้สร้างไฟล์ชื่อ .env
ในรากของโปรเจ็กต์ของคุณ:
REACT_APP_SECRET_CODE=abcdef
หมายเหตุ: คุณต้องสร้างตัวแปรสภาพแวดล้อมที่กำหนดเองโดยขึ้นต้นด้วย
REACT_APP_
ตัวแปรอื่นๆ ยกเว้นNODE_ENV
จะถูกละเว้นเพื่อหลีกเลี่ยงการเปิดเผยคีย์ส่วนตัวบนเครื่องที่อาจมีชื่อเดียวกันโดยไม่ตั้งใจ การเปลี่ยนแปลงตัวแปรสภาพแวดล้อมจะทำให้คุณต้องรีสตาร์ทเซิร์ฟเวอร์การพัฒนาหากเซิร์ฟเวอร์กำลังทำงานอยู่
ควร ตรวจสอบไฟล์ .env
ในการควบคุมแหล่งที่มา (ยกเว้น .env*.local
)
.env
อื่นๆ ใดบ้างที่สามารถใช้ได้หมายเหตุ: คุณลักษณะนี้ ใช้ได้กับ
[email protected]
และสูงกว่า
.env
: ค่าเริ่มต้น.env.local
: การแทนที่ในเครื่อง ไฟล์นี้ถูกโหลดสำหรับทุกสภาพแวดล้อมยกเว้นการทดสอบ.env.development
, .env.test
, .env.production
: การตั้งค่าเฉพาะสภาพแวดล้อม.env.development.local
, .env.test.local
, .env.production.local
: การแทนที่การตั้งค่าเฉพาะสภาพแวดล้อมภายในเครื่องไฟล์ทางด้านซ้ายมีความสำคัญมากกว่าไฟล์ทางด้านขวา:
npm start
: .env.development.local
, .env.development
, .env.local
, .env
npm run build
: .env.production.local
, .env.production
, .env.local
, .env
npm test
: .env.test.local
, .env.test
, .env
(หมายเหตุ .env.local
หายไป) ตัวแปรเหล่านี้จะทำหน้าที่เป็นค่าเริ่มต้นหากเครื่องไม่ได้ตั้งค่าไว้อย่างชัดเจน
โปรดดูเอกสาร Dotenv สำหรับรายละเอียดเพิ่มเติม
หมายเหตุ: หากคุณกำหนดตัวแปรสภาพแวดล้อมสำหรับการพัฒนาแพลตฟอร์ม CI และ/หรือโฮสติ้งของคุณมักจะต้องการสิ่งเหล่านี้เช่นกัน ปรึกษาเอกสารของพวกเขาวิธีการทำเช่นนี้ ตัวอย่างเช่นดูเอกสารสำหรับ Travis CI หรือ Heroku
.env
หมายเหตุ: คุณลักษณะนี้สามารถใช้ได้กับ
[email protected]
และสูงกว่า
ขยายตัวแปรที่มีอยู่แล้วบนเครื่องของคุณเพื่อใช้ในไฟล์ .env
ของคุณ (โดยใช้ DOTENV-EXPAND)
ตัวอย่างเช่นเพื่อรับตัวแปรสภาพแวดล้อม npm_package_version
:
REACT_APP_VERSION=$npm_package_version
# also works:
# REACT_APP_VERSION=${npm_package_version}
หรือขยายตัวแปรท้องถิ่นไปยังไฟล์ .env
ปัจจุบัน:
DOMAIN=www.example.com
REACT_APP_FOO=$DOMAIN/foo
REACT_APP_BAR=$DOMAIN/bar
ห้องสมุดยอดนิยมหลายแห่งใช้นักตกแต่งในเอกสารของพวกเขา
สร้างแอป React ไม่รองรับไวยากรณ์ของมัณฑนากรในขณะนี้เพราะ:
อย่างไรก็ตามในหลายกรณีคุณสามารถเขียนโค้ดที่ใช้งานตกแต่งโดยไม่ต้องตกแต่งได้ดี
โปรดดูสองเธรดนี้สำหรับการอ้างอิง:
สร้างแอป React จะเพิ่มการรองรับมัณฑนากรเมื่อข้อกำหนดจะเข้าสู่ขั้นตอนที่มั่นคง
React ไม่ได้กำหนดวิธีการเฉพาะในการดึงข้อมูล แต่คนทั่วไปมักใช้ห้องสมุดเช่น Axios หรือ API fetch()
API ที่ได้รับจากเบราว์เซอร์ สะดวกสร้างแอป React รวมถึง polyfill สำหรับ fetch()
เพื่อให้คุณสามารถใช้งานได้โดยไม่ต้องกังวลเกี่ยวกับการสนับสนุนเบราว์เซอร์
ฟังก์ชั่น fetch
ทั่วโลกช่วยให้สามารถร้องขอ AJAX ได้อย่างง่ายดาย ใช้เวลาใน URL เป็นอินพุตและส่งคืน Promise
ที่แก้ไขไปยังวัตถุ Response
คุณสามารถค้นหาข้อมูลเพิ่มเติมเกี่ยวกับ fetch
ได้ที่นี่
โครงการนี้ยังรวมถึง Polyfill สัญญาซึ่งให้การดำเนินการอย่างเต็มรูปแบบของสัญญา/A+ สัญญาแสดงถึงผลลัพธ์ในที่สุดของการดำเนินการแบบอะซิงโครนัสคุณสามารถค้นหาข้อมูลเพิ่มเติมเกี่ยวกับสัญญาที่นี่และที่นี่ ทั้ง Axios และ fetch()
ใช้สัญญาภายใต้ประทุน นอกจากนี้คุณยังสามารถใช้ไวยากรณ์ async / await
เพื่อลดการทำรังการโทรกลับ
คุณสามารถเรียนรู้เพิ่มเติมเกี่ยวกับการทำคำขอ AJAX จากส่วนประกอบ React ในรายการคำถามที่พบบ่อยในเว็บไซต์ React
บทเรียนเหล่านี้จะช่วยให้คุณรวมแอปของคุณเข้ากับแบ็กเอนด์ API ที่ทำงานบนพอร์ตอื่นโดยใช้ fetch()
เพื่อเข้าถึง
ตรวจสอบบทช่วยสอนนี้ คุณสามารถค้นหาที่เก็บสหาย GitHub ได้ที่นี่
ตรวจสอบบทช่วยสอนนี้ คุณสามารถค้นหาที่เก็บสหาย GitHub ได้ที่นี่
หมายเหตุ: คุณลักษณะนี้สามารถใช้ได้กับ
[email protected]
และสูงกว่า
ผู้คนมักจะให้บริการแอพ React Front-End จากโฮสต์และพอร์ตเดียวกันกับการใช้งานแบ็กเอนด์
ตัวอย่างเช่นการตั้งค่าการผลิตอาจมีลักษณะเช่นนี้หลังจากปรับใช้แอป:
/ - static server returns index.html with React app
/todos - static server returns index.html with React app
/api/todos - server handles any /api/* requests using the backend implementation
ไม่ จำเป็นต้องตั้งค่าดังกล่าว อย่างไรก็ตามหากคุณ มี การตั้งค่าเช่นนี้มันจะสะดวกในการเขียนคำขอเช่น fetch('/api/todos')
โดยไม่ต้องกังวลเกี่ยวกับการเปลี่ยนเส้นทางไปยังโฮสต์หรือพอร์ตอื่นในระหว่างการพัฒนา
หากต้องการบอกให้เซิร์ฟเวอร์การพัฒนาพร็อกซีคำขอที่ไม่รู้จักใด ๆ ไปยังเซิร์ฟเวอร์ API ของคุณในการพัฒนาให้เพิ่มฟิลด์ proxy
ลงใน package.json
ของคุณตัวอย่างเช่น:
"proxy" : "http://localhost:4000" ,
ด้วยวิธีนี้เมื่อคุณ fetch('/api/todos')
ในการพัฒนาเซิร์ฟเวอร์การพัฒนาจะรับรู้ว่ามันไม่ใช่สินทรัพย์คงที่และจะส่งคำขอของคุณไปที่ http://localhost:4000/api/todos
เป็นทางเลือก เซิร์ฟเวอร์การพัฒนาจะ พยายาม ส่งคำขอโดยไม่มี text/html
ในส่วนหัว Accept
ไปยังพร็อกซี
สิ่งนี้หลีกเลี่ยงปัญหา CORS และข้อความแสดงข้อผิดพลาดเช่นนี้ในการพัฒนา:
Fetch API cannot load http://localhost:4000/api/todos. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:3000' is therefore not allowed access. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
โปรดทราบว่า proxy
มีผลเฉพาะในการพัฒนา (ด้วย npm start
) และขึ้นอยู่กับคุณเพื่อให้แน่ใจว่า URL เช่น /api/todos
ชี้ไปที่สิ่งที่ถูกต้องในการผลิต คุณไม่จำเป็นต้องใช้คำนำหน้า /api
คำขอใด ๆ ที่ไม่รู้จักโดยไม่มีส่วนหัวที่ยอมรับ text/html
จะถูกเปลี่ยนเส้นทางไปยัง proxy
ที่ระบุ
ตัวเลือก proxy
รองรับการเชื่อมต่อ HTTP, HTTPS และ WebSocket
หากตัวเลือก proxy
ไม่ ยืดหยุ่นเพียงพอสำหรับคุณหรือคุณสามารถ:
เมื่อคุณเปิดใช้งานตัวเลือก proxy
คุณจะเลือกชุดตรวจสอบโฮสต์ที่เข้มงวดมากขึ้น สิ่งนี้จำเป็นเนื่องจากการเปิดแบ็กเอนด์ที่เปิดไปยังโฮสต์ระยะไกลทำให้คอมพิวเตอร์ของคุณมีความเสี่ยงต่อการโจมตี DNS Rebinding ปัญหานี้อธิบายไว้ในบทความนี้และปัญหานี้
สิ่งนี้ไม่ควรส่งผลกระทบต่อคุณเมื่อพัฒนาใน localhost
แต่ถ้าคุณพัฒนาจากระยะไกลตามที่อธิบายไว้ที่นี่คุณจะเห็นข้อผิดพลาดนี้ในเบราว์เซอร์หลังจากเปิดใช้งานตัวเลือก proxy
:
ส่วนหัวโฮสต์ที่ไม่ถูกต้อง
ในการแก้ไขปัญหาคุณสามารถระบุโฮสต์การพัฒนาสาธารณะของคุณในไฟล์ที่เรียกว่า .env.development
ในรากของโครงการของคุณ:
HOST=mypublicdevhost.com
หากคุณรีสตาร์ทเซิร์ฟเวอร์การพัฒนาตอนนี้และโหลดแอพจากโฮสต์ที่ระบุก็ควรใช้งานได้
หากคุณยังคงมีปัญหาหรือหากคุณใช้สภาพแวดล้อมที่แปลกใหม่เช่นตัวแก้ไขคลาวด์คุณสามารถข้ามการตรวจสอบโฮสต์ได้อย่างสมบูรณ์โดยการเพิ่มบรรทัดไปยัง. .env.development.local
โปรดทราบว่านี่เป็นอันตรายและทำให้เครื่องของคุณมีการดำเนินการรหัสระยะไกลจากเว็บไซต์ที่เป็นอันตราย:
# NOTE: THIS IS DANGEROUS!
# It exposes your machine to attacks from the websites you visit.
DANGEROUSLY_DISABLE_HOST_CHECK=true
เราไม่แนะนำวิธีการนี้
หมายเหตุ: คุณลักษณะนี้มีให้กับ
[email protected]
และสูงกว่า
หากตัวเลือก proxy
ไม่ ยืดหยุ่นเพียงพอสำหรับคุณคุณสามารถระบุวัตถุในแบบฟอร์มต่อไปนี้ (ใน package.json
)
นอกจากนี้คุณยังสามารถระบุค่าการกำหนดค่าใด ๆ http-proxy-middleware
หรือสนับสนุน http-proxy
{
// ...
"proxy" : {
"/api" : {
"target" : "<url>" ,
"ws" : true
// ...
}
}
// ...
}
คำขอทั้งหมดที่ตรงกับเส้นทางนี้จะเป็นพร็อกซีโดยไม่มีข้อยกเว้น ซึ่งรวมถึงคำขอสำหรับ text/html
ซึ่งตัวเลือก proxy
มาตรฐานไม่ได้พร็อกซี
หากคุณต้องการระบุพร็อกซีหลายตัวคุณสามารถทำได้โดยระบุรายการเพิ่มเติม การจับคู่เป็นนิพจน์ทั่วไปเพื่อให้คุณสามารถใช้ regexp เพื่อจับคู่หลายเส้นทาง
{
// ...
"proxy" : {
// Matches any request starting with /api
"/api" : {
"target" : "<url_1>" ,
"ws" : true
// ...
} ,
// Matches any request starting with /foo
"/foo" : {
"target" : "<url_2>" ,
"ssl" : true ,
"pathRewrite" : {
"^/foo" : "/foo/beta"
}
// ...
} ,
// Matches /bar/abc.html but not /bar/sub/def.html
"/bar/[^/]*[.]html" : {
"target" : "<url_3>" ,
// ...
} ,
// Matches /baz/abc.html and /baz/sub/def.html
"/baz/.*/.*[.]html" : {
"target" : "<url_4>"
// ...
}
}
// ...
}
เมื่อตั้งค่าพร็อกซี WebSocket มีข้อควรพิจารณาเพิ่มเติมบางประการที่ต้องระวัง
หากคุณใช้เอ็นจิ้น websocket เช่น socket.io คุณต้องมีเซิร์ฟเวอร์ socket.io ที่ทำงานซึ่งคุณสามารถใช้เป็นเป้าหมายพร็อกซี socket.io จะไม่ทำงานกับเซิร์ฟเวอร์ WebSocket มาตรฐาน โดยเฉพาะอย่าคาดหวังว่า socket.io จะทำงานกับการทดสอบ websocket.org echo
มีเอกสารที่ดีสำหรับการตั้งค่า Socket.io Server
WebSockets มาตรฐาน จะ ทำงานกับเซิร์ฟเวอร์ WebSocket มาตรฐานรวมถึงการทดสอบ echo websocket.org Echo คุณสามารถใช้ไลบรารีเช่น WS สำหรับเซิร์ฟเวอร์ด้วย websockets ดั้งเดิมในเบราว์เซอร์
ไม่ว่าจะด้วยวิธีใดคุณสามารถร้องขอพร็อกซี WebSocket ได้ด้วยตนเองใน package.json
:
{
// ...
"proxy" : {
"/socket" : {
// Your compatible WebSocket server
"target" : "ws://<socket_url>" ,
// Tell http-proxy-middleware that this is a WebSocket proxy.
// Also allows you to proxy WebSocket requests without an additional HTTP request
// https://github.com/chimurai/http-proxy-middleware#external-websocket-upgrade
"ws" : true
// ...
}
}
// ...
}
หมายเหตุ: คุณลักษณะนี้มีให้กับ
[email protected]
และสูงกว่า
คุณอาจต้องการเซิร์ฟเวอร์ dev เพื่อให้บริการหน้าผ่าน https กรณีหนึ่งโดยเฉพาะที่อาจเป็นประโยชน์คือเมื่อใช้คุณสมบัติ "พร็อกซี" เพื่อขอพร็อกซีไปยังเซิร์ฟเวอร์ API เมื่อเซิร์ฟเวอร์ API นั้นให้บริการ HTTPS
ในการทำเช่นนี้ให้ตั้งค่าตัวแปรสภาพแวดล้อม HTTPS
เป็น true
จากนั้นเริ่มเซิร์ฟเวอร์ dev ตามปกติด้วย npm start
:
set HTTPS = true && npm start
( $ env: HTTPS = $true ) -and (npm start)
(หมายเหตุ: การขาดช่องว่างเป็นความตั้งใจ)
HTTPS=true npm start
โปรดทราบว่าเซิร์ฟเวอร์จะใช้ใบรับรองที่ลงนามด้วยตนเองดังนั้นเว็บเบราว์เซอร์ของคุณจะแสดงคำเตือนเมื่อเข้าถึงหน้าเว็บได้อย่างแน่นอน
<meta>
บนเซิร์ฟเวอร์ เนื่องจากแอพสร้างปฏิกิริยาไม่รองรับการเรนเดอร์เซิร์ฟเวอร์คุณอาจสงสัยว่าจะสร้างแท็ก <meta>
แบบไดนามิกและสะท้อน URL ปัจจุบันได้อย่างไร ในการแก้ปัญหานี้เราขอแนะนำให้เพิ่มตัวยึดตำแหน่งลงใน HTML เช่นนี้:
<!doctype html >
< html lang =" en " >
< head >
< meta property =" og:title " content =" __OG_TITLE__ " >
< meta property =" og:description " content =" __OG_DESCRIPTION__ " >
จากนั้นบนเซิร์ฟเวอร์โดยไม่คำนึงถึงแบ็กเอนด์ที่คุณใช้คุณสามารถอ่าน index.html
ลงในหน่วยความจำและแทนที่ __OG_TITLE__
, __OG_DESCRIPTION__
และตัวยึดตำแหน่งอื่น ๆ ที่มีค่าขึ้นอยู่กับ URL ปัจจุบัน เพียงตรวจสอบให้แน่ใจว่าได้ฆ่าเชื้อและหลบหนีค่าที่ถูกแก้ไขเพื่อให้พวกเขาปลอดภัยที่จะฝังลงใน HTML!
หากคุณใช้โหนดเซิร์ฟเวอร์คุณสามารถแชร์ตรรกะการจับคู่เส้นทางระหว่างไคลเอนต์และเซิร์ฟเวอร์ อย่างไรก็ตามการทำซ้ำมันยังใช้งานได้ดีในกรณีง่ายๆ
หากคุณกำลังโฮสต์ build
ของคุณกับผู้ให้บริการโฮสต์แบบคงที่คุณสามารถใช้ React-SNAPSHOT หรือ React-SNAP เพื่อสร้างหน้า HTML สำหรับแต่ละเส้นทางหรือลิงก์สัมพัทธ์ในแอปพลิเคชันของคุณ หน้าเหล่านี้จะกลายเป็นอย่างราบรื่นหรือ“ ชุ่มชื้น” เมื่อชุด JavaScript โหลด
นอกจากนี้ยังมีโอกาสที่จะใช้สิ่งนี้นอกโฮสติ้งแบบคงที่เพื่อลดแรงกดดันจากเซิร์ฟเวอร์เมื่อสร้างและแคชเส้นทาง
ประโยชน์หลักของการแสดงผลก่อนคือคุณจะได้รับเนื้อหาหลักของแต่ละหน้า ด้วย HTML Payload-ไม่ว่าจะดาวน์โหลดชุด JavaScript ของคุณได้สำเร็จหรือไม่ นอกจากนี้ยังเพิ่มโอกาสที่แต่ละเส้นทางของแอปพลิเคชันของคุณจะถูกหยิบขึ้นมาโดยเครื่องมือค้นหา
คุณสามารถอ่านเพิ่มเติมเกี่ยวกับการกำหนดค่าล่วงหน้าเป็นศูนย์ (เรียกอีกอย่างว่า Snapshotting) ที่นี่
ในทำนองเดียวกันกับส่วนก่อนหน้านี้คุณสามารถทิ้งตำแหน่งผู้ถือไว้ใน HTML ที่ฉีดตัวแปรทั่วโลกเช่น:
< ! doctype html >
< html lang = "en" >
< head >
< script >
window.SERVER_DATA = __SERVER_DATA__;
</ script >
จากนั้นบนเซิร์ฟเวอร์คุณสามารถแทนที่ __SERVER_DATA__
ด้วย JSON ของข้อมูลจริงก่อนที่จะส่งการตอบกลับ รหัสไคลเอนต์สามารถอ่าน window.SERVER_DATA
เพื่อใช้งานได้ ตรวจสอบให้แน่ใจว่าได้ฆ่าเชื้อ JSON ก่อนที่จะส่งไปยังลูกค้าเนื่องจากแอปของคุณเสี่ยงต่อการโจมตี XSS
หมายเหตุ: คุณลักษณะนี้มีให้เลือกด้วย
[email protected]
และสูงกว่า
อ่านคู่มือการโยกย้ายเพื่อเรียนรู้วิธีเปิดใช้งานในโครงการเก่า!
สร้างแอป React ใช้ Jest เป็นนักวิ่งทดสอบ เพื่อเตรียมพร้อมสำหรับการบูรณาการนี้เราได้ทำการปรับปรุงความตลกขบขันครั้งใหญ่ดังนั้นหากคุณได้ยินสิ่งเลวร้ายเกี่ยวกับเรื่องนี้เมื่อหลายปีก่อนลองดูอีกครั้ง
Jest เป็นนักวิ่งที่ใช้โหนด ซึ่งหมายความว่าการทดสอบจะทำงานในสภาพแวดล้อมโหนดเสมอและไม่ได้อยู่ในเบราว์เซอร์จริง สิ่งนี้ช่วยให้เราเปิดใช้งานความเร็วการวนซ้ำที่รวดเร็วและป้องกันไม่ให้มีความขรุขระ
ในขณะที่ JEST จัดหาเบราว์เซอร์ไปทั่วโลกเช่น window
ขอบคุณ JSDOM พวกเขาเป็นเพียงการประมาณของพฤติกรรมเบราว์เซอร์ที่แท้จริง Jest มีจุดประสงค์เพื่อใช้สำหรับการทดสอบหน่วยของตรรกะและส่วนประกอบของคุณมากกว่า Dom Quirks
เราขอแนะนำให้คุณใช้เครื่องมือแยกต่างหากสำหรับการทดสอบแบบครบวงจรของเบราว์เซอร์หากคุณต้องการ พวกเขาอยู่นอกเหนือขอบเขตของการสร้างแอป React
Jest จะค้นหาไฟล์ทดสอบที่มีการประชุมการตั้งชื่อยอดนิยมใด ๆ ต่อไปนี้:
.js
ต่อท้ายในโฟลเดอร์ __tests__
.test.js
ต่อท้าย.spec.js
ต่อท้าย ไฟล์ .test.js
/ .spec.js
(หรือโฟลเดอร์ __tests__
) สามารถอยู่ที่ระดับความลึกใด ๆ ภายใต้โฟลเดอร์ src
Top Level
เราขอแนะนำให้วางไฟล์ทดสอบ (หรือ __tests__
โฟลเดอร์) ถัดจากรหัสที่พวกเขากำลังทดสอบเพื่อให้การนำเข้าสัมพัทธ์จะสั้นลง ตัวอย่างเช่นหาก App.test.js
และ App.js
อยู่ในโฟลเดอร์เดียวกันการทดสอบเพียงแค่ต้อง import App from './App'
แทนที่จะเป็นเส้นทางที่สัมพันธ์กันยาว Colocation ยังช่วยค้นหาการทดสอบได้เร็วขึ้นในโครงการขนาดใหญ่
เมื่อคุณเรียกใช้ npm test
Jest จะเปิดตัวในโหมดนาฬิกา ทุกครั้งที่คุณบันทึกไฟล์มันจะเรียกใช้การทดสอบอีกครั้งเช่นเดียวกับ npm start
รวบรวมรหัสใหม่
ผู้เฝ้าดูมีอินเทอร์เฟซบรรทัดคำสั่งแบบโต้ตอบที่มีความสามารถในการเรียกใช้การทดสอบทั้งหมดหรือมุ่งเน้นไปที่รูปแบบการค้นหา มันได้รับการออกแบบด้วยวิธีนี้เพื่อให้คุณสามารถเปิดและเพลิดเพลินกับการวิ่งใหม่อย่างรวดเร็ว คุณสามารถเรียนรู้คำสั่งจาก "ดูการใช้งาน" ทราบว่าผู้เฝ้าดูพิมพ์หลังจากการวิ่งทุกครั้ง:
โดยค่าเริ่มต้นเมื่อคุณเรียกใช้ npm test
JEST จะเรียกใช้การทดสอบที่เกี่ยวข้องกับไฟล์ที่เปลี่ยนแปลงไปตั้งแต่การประชุมครั้งล่าสุด นี่คือการเพิ่มประสิทธิภาพที่ออกแบบมาเพื่อให้การทดสอบของคุณทำงานได้อย่างรวดเร็วโดยไม่คำนึงถึงจำนวนการทดสอบที่คุณมี อย่างไรก็ตามสันนิษฐานว่าคุณไม่ได้ใช้รหัสที่ไม่ผ่านการทดสอบ
JEST จะพูดถึงอย่างชัดเจนเสมอว่ามันใช้การทดสอบที่เกี่ยวข้องกับไฟล์ที่เปลี่ยนแปลงไปตั้งแต่การประชุมครั้งสุดท้าย นอกจากนี้คุณยังสามารถกด a
ในโหมดนาฬิกาเพื่อบังคับให้ jest เรียกใช้การทดสอบทั้งหมด
JEST จะเรียกใช้การทดสอบทั้งหมดบนเซิร์ฟเวอร์การรวมอย่างต่อเนื่องหรือหากโครงการไม่ได้อยู่ในพื้นที่เก็บข้อมูล GIT หรือ Mercurial
ในการสร้างการทดสอบให้เพิ่มบล็อก it()
หรือ test()
) ด้วยชื่อของการทดสอบและรหัส คุณอาจเลือกห่อไว้ใน describe()
บล็อกสำหรับการจัดกลุ่มแบบลอจิคัล แต่ไม่จำเป็นหรือแนะนำ
Jest ให้ฟังก์ชั่นระดับโลก expect()
สำหรับการยืนยัน การทดสอบพื้นฐานอาจมีลักษณะเช่นนี้:
import sum from './sum' ;
it ( 'sums numbers' , ( ) => {
expect ( sum ( 1 , 2 ) ) . toEqual ( 3 ) ;
expect ( sum ( 2 , 2 ) ) . toEqual ( 4 ) ;
} ) ;
ทุกคน expect()
ผู้จับคู่ที่ได้รับการสนับสนุนโดย JEST ได้รับการบันทึกไว้อย่างกว้างขวางที่นี่
นอกจากนี้คุณยังสามารถใช้ jest.fn()
และ expect(fn).toBeCalled()
เพื่อสร้าง "สายลับ" หรือฟังก์ชั่นจำลอง
มีเทคนิคการทดสอบส่วนประกอบในวงกว้าง พวกเขามีตั้งแต่“ การทดสอบควัน” ตรวจสอบว่าส่วนประกอบที่แสดงผลโดยไม่ต้องขว้างไปจนถึงการเรนเดอร์ตื้นและทดสอบผลลัพธ์บางอย่างไปจนถึงการเรนเดอร์เต็มรูปแบบและการทดสอบวงจรชีวิตส่วนประกอบและการเปลี่ยนแปลงสถานะ
โครงการที่แตกต่างกันเลือกการทดสอบการทดสอบที่แตกต่างกันตามความถี่ของการเปลี่ยนแปลงส่วนประกอบและจำนวนตรรกะที่พวกเขามี หากคุณยังไม่ได้ตัดสินใจเกี่ยวกับกลยุทธ์การทดสอบเราขอแนะนำให้คุณเริ่มต้นด้วยการสร้างการทดสอบควันง่ายๆสำหรับส่วนประกอบของคุณ:
import React from 'react' ;
import ReactDOM from 'react-dom' ;
import App from './App' ;
it ( 'renders without crashing' , ( ) => {
const div = document . createElement ( 'div' ) ;
ReactDOM . render ( < App /> , div ) ;
} ) ;
การทดสอบนี้ติดตั้งส่วนประกอบและทำให้แน่ใจว่ามันไม่ได้โยนระหว่างการแสดงผล การทดสอบเช่นนี้ให้คุณค่ามากมายด้วยความพยายามเพียงเล็กน้อยดังนั้นพวกเขาจึงเป็นจุดเริ่มต้นและนี่คือการทดสอบที่คุณจะพบใน src/App.test.js
เมื่อคุณพบข้อบกพร่องที่เกิดจากการเปลี่ยนส่วนประกอบคุณจะได้รับข้อมูลเชิงลึกที่ลึกซึ้งยิ่งขึ้นว่าส่วนใดของพวกเขาที่ควรค่าแก่การทดสอบในแอปพลิเคชันของคุณ นี่อาจเป็นเวลาที่ดีในการแนะนำการทดสอบที่เฉพาะเจาะจงมากขึ้นซึ่งเป็นการแสดงผลหรือพฤติกรรมที่คาดหวัง
หากคุณต้องการทดสอบส่วนประกอบที่แยกออกจากส่วนประกอบเด็กที่พวกเขาแสดงผลเราขอแนะนำให้ใช้ API การเรนเดอร์ shallow()
จากเอนไซม์ ในการติดตั้ง Run:
npm install --save enzyme enzyme-adapter-react-16 react-test-renderer
หรือคุณอาจใช้ yarn
:
yarn add enzyme enzyme-adapter-react-16 react-test-renderer
ในฐานะของเอนไซม์ 3 คุณจะต้องติดตั้งเอนไซม์พร้อมกับอะแดปเตอร์ที่สอดคล้องกับเวอร์ชันของปฏิกิริยาที่คุณใช้ (ตัวอย่างข้างต้นใช้อะแดปเตอร์สำหรับ React 16. )
อะแดปเตอร์จะต้องกำหนดค่าในไฟล์การตั้งค่าส่วนกลางของคุณ:
src/setupTests.js
import { configure } from 'enzyme' ;
import Adapter from 'enzyme-adapter-react-16' ;
configure ( { adapter : new Adapter ( ) } ) ;
หมายเหตุ: โปรดจำไว้ว่าหากคุณตัดสินใจที่จะ "ดีด" ก่อนที่จะสร้าง
src/setupTests.js
ไฟล์ที่ได้ผลลัพธ์package.json
จะไม่มีการอ้างอิงใด ๆ อ่านที่นี่เพื่อเรียนรู้วิธีเพิ่มสิ่งนี้หลังจากออก
ตอนนี้คุณสามารถเขียนการทดสอบควันด้วย:
import React from 'react' ;
import { shallow } from 'enzyme' ;
import App from './App' ;
it ( 'renders without crashing' , ( ) => {
shallow ( < App /> ) ;
} ) ;
ซึ่งแตกต่างจากการทดสอบควันก่อนหน้านี้โดยใช้ ReactDOM.render()
การทดสอบนี้จะแสดงผลเฉพาะ <App>
และไม่ลึกลงไป ตัวอย่างเช่นแม้ว่า <App>
จะแสดงผล <Button>
ที่โยนการทดสอบนี้จะผ่านไปแล้ว การเรนเดอร์ตื้นนั้นยอดเยี่ยมสำหรับการทดสอบหน่วยที่แยกได้ แต่คุณอาจต้องการสร้างการทดสอบการเรนเดอร์เต็มรูปแบบเพื่อให้แน่ใจว่าส่วนประกอบรวมเข้าด้วยกันอย่างถูกต้อง เอนไซม์รองรับการเรนเดอร์เต็มรูปแบบด้วย mount()
และคุณยังสามารถใช้สำหรับการทดสอบการเปลี่ยนแปลงสถานะและวงจรชีวิตส่วนประกอบ
คุณสามารถอ่านเอกสารประกอบของเอนไซม์สำหรับเทคนิคการทดสอบเพิ่มเติม เอกสารของเอนไซม์ใช้ชัยและไซลอนสำหรับการยืนยัน แต่คุณไม่จำเป็นต้องใช้เพราะ jest ให้ expect()
และ jest.fn()
สำหรับสายลับ
นี่คือตัวอย่างจากเอกสารของเอนไซม์ที่ยืนยันผลลัพธ์ที่เฉพาะเจาะจงเขียนใหม่เพื่อใช้ jest matchers:
import React from 'react' ;
import { shallow } from 'enzyme' ;
import App from './App' ;
it ( 'renders welcome message' , ( ) => {
const wrapper = shallow ( < App /> ) ;
const welcome = < h2 > Welcome to React </ h2 > ;
// expect(wrapper.contains(welcome)).to.equal(true);
expect ( wrapper . contains ( welcome ) ) . toEqual ( true ) ;
} ) ;
ผู้จับคู่ที่ตลกขบขันทั้งหมดได้รับการบันทึกไว้อย่างกว้างขวางที่นี่
อย่างไรก็ตามคุณสามารถใช้ห้องสมุดการยืนยันบุคคลที่สามเช่นชัยถ้าคุณต้องการตามที่อธิบายไว้ด้านล่าง
นอกจากนี้คุณอาจพบว่า jest-enzyme มีประโยชน์ในการทำให้การทดสอบของคุณง่ายขึ้นด้วยเครื่องจับคู่ที่อ่านได้ ด้านบน contains
รหัสสามารถเขียนได้ง่ายขึ้นด้วย jest-enzyme
expect ( wrapper ) . toContainReact ( welcome )
หากต้องการเปิดใช้งานสิ่งนี้ให้ติดตั้ง jest-enzyme
:
npm install --save jest-enzyme
หรือคุณอาจใช้ yarn
:
yarn add jest-enzyme
นำเข้าใน src/setupTests.js
เพื่อให้การจับคู่พร้อมใช้งานในการทดสอบทุกครั้ง:
import 'jest-enzyme' ;
เราขอแนะนำให้คุณใช้ expect()
สำหรับการยืนยันและ jest.fn()
สำหรับสายลับ หากคุณมีปัญหากับพวกเขาโปรดยื่นเรื่องเหล่านั้นกับความตลกขบขันและเราจะแก้ไขพวกเขา เราตั้งใจที่จะทำให้พวกเขาดีขึ้นสำหรับการตอบสนองการสนับสนุนเช่นองค์ประกอบการตอบสนองที่พิมพ์ได้สวยเป็น JSX
อย่างไรก็ตามหากคุณคุ้นเคยกับห้องสมุดอื่น ๆ เช่นชัยและไซลอนหรือหากคุณมีรหัสที่มีอยู่โดยใช้พวกเขาที่คุณต้องการพอร์ตคุณสามารถนำเข้าได้ตามปกติเช่นนี้:
import sinon from 'sinon' ;
import { expect } from 'chai' ;
จากนั้นใช้ในการทดสอบของคุณเหมือนปกติ
หมายเหตุ: คุณลักษณะนี้มีให้กับ
[email protected]
และสูงกว่า
หากแอปของคุณใช้ API เบราว์เซอร์ที่คุณต้องล้อเลียนในการทดสอบของคุณหรือหากคุณต้องการการตั้งค่าทั่วโลกก่อนที่จะทำการทดสอบให้เพิ่ม src/setupTests.js
ลงในโครงการของคุณ มันจะถูกดำเนินการโดยอัตโนมัติก่อนที่จะทำการทดสอบของคุณ
ตัวอย่างเช่น:
src/setupTests.js
const localStorageMock = {
getItem : jest . fn ( ) ,
setItem : jest . fn ( ) ,
clear : jest . fn ( )
} ;
global . localStorage = localStorageMock
หมายเหตุ: โปรดทราบว่าหากคุณตัดสินใจที่จะ "ดีด" ก่อนที่จะสร้าง
src/setupTests.js
ไฟล์package.json
ที่ได้จะไม่มีการอ้างอิงใด ๆ ดังนั้นคุณควรสร้างคุณสมบัติsetupTestFrameworkScriptFile
ด้วยตนเองในการกำหนดค่า สิ่งต่อไปนี้:
"jest" : { // ... "setupTestFrameworkScriptFile" : "<rootDir>/src/setupTests.js" }
คุณสามารถแทนที่ it()
ด้วย xit()
เพื่อแยกการทดสอบชั่วคราวจากการดำเนินการ
ในทำนองเดียวกัน fit()
ช่วยให้คุณมุ่งเน้นไปที่การทดสอบเฉพาะโดยไม่ต้องทำการทดสอบอื่น ๆ
Jest มีนักข่าวครอบคลุมในตัวที่ทำงานได้ดีกับ ES6 และไม่จำเป็นต้องมีการกำหนดค่า
เรียกใช้ npm test -- --coverage
(หมายเหตุเพิ่มเติม --
อยู่ตรงกลาง) เพื่อรวมรายงานความครอบคลุมเช่นนี้:
โปรดทราบว่าการทดสอบทำงานช้าลงมากด้วยความครอบคลุมดังนั้นจึงขอแนะนำให้เรียกใช้แยกต่างหากจากเวิร์กโฟลว์ปกติของคุณ
การกำหนดค่าความครอบคลุมของ JEST เริ่มต้นสามารถเอาชนะได้โดยการเพิ่มปุ่มใด ๆ ที่รองรับต่อไปนี้ลงในการกำหนดค่า jest ใน package.json ของคุณ
รองรับการแทนที่:
collectCoverageFrom
coverageReporters
coverageThreshold
snapshotSerializers
ตัวอย่าง package.json:
{
"name" : " your-package " ,
"jest" : {
"collectCoverageFrom" : [
" src/**/*.{js,jsx} " ,
" !<rootDir>/node_modules/ " ,
" !<rootDir>/path/to/dir/ "
],
"coverageThreshold" : {
"global" : {
"branches" : 90 ,
"functions" : 90 ,
"lines" : 90 ,
"statements" : 90
}
},
"coverageReporters" : [ " text " ],
"snapshotSerializers" : [ " my-serializer-module " ]
}
}
โดยค่าเริ่มต้น npm test
จะเรียกใช้ Watcher ด้วย Interactive CLI อย่างไรก็ตามคุณสามารถบังคับให้เรียกใช้การทดสอบหนึ่งครั้งและเสร็จสิ้นกระบวนการโดยการตั้งค่าตัวแปรสภาพแวดล้อมที่เรียกว่า CI
เมื่อสร้างการสร้างแอปพลิเคชันของคุณด้วย npm run build
Linter คำเตือนจะไม่ถูกตรวจสอบตามค่าเริ่มต้น เช่น npm test
คุณสามารถบังคับให้สร้างเพื่อทำการตรวจสอบคำเตือน linter โดยการตั้งค่าตัวแปรสภาพแวดล้อม CI
หากพบคำเตือนใด ๆ การสร้างจะล้มเหลว
เซิร์ฟเวอร์ CI ยอดนิยมตั้งค่าตัวแปรสภาพแวดล้อม CI
โดยค่าเริ่มต้นแล้ว แต่คุณสามารถทำได้ด้วยตัวเองด้วย:
.travis.yml
ลงในที่เก็บ Git ของคุณ language: node_js
node_js:
- 6
cache:
directories:
- node_modules
script:
- npm run build
- npm test
ติดตามบทความนี้เพื่อตั้งค่า Circleci ด้วยโครงการ Create React App
set CI = true && npm test
set CI = true && npm run build
(หมายเหตุ: การขาดช่องว่างเป็นความตั้งใจ)
( $ env: CI = $true ) -and (npm test)
( $ env: CI = $true ) -and (npm run build)
CI=true npm test
CI=true npm run build
คำสั่งทดสอบจะบังคับให้ jest ทำการทดสอบหนึ่งครั้งแทนที่จะเปิดตัวนักดู
หากคุณพบว่าตัวเองทำสิ่งนี้บ่อยครั้งในการพัฒนาโปรดยื่นปัญหาเพื่อบอกเราเกี่ยวกับกรณีการใช้งานของคุณเพราะเราต้องการทำให้ผู้เฝ้าดูเป็นประสบการณ์ที่ดีที่สุดและเปิดให้เปลี่ยนวิธีการทำงานเพื่อรองรับเวิร์กโฟลว์มากขึ้น
คำสั่ง build จะตรวจสอบคำเตือน linter และล้มเหลวหากพบ
โดยค่าเริ่มต้น package.json
ของโครงการที่สร้างขึ้นจะเป็นแบบนี้:
"scripts" : {
"start" : "react-scripts start" ,
"build" : "react-scripts build" ,
"test" : "react-scripts test --env=jsdom"
หากคุณรู้ว่าไม่มีการทดสอบของคุณขึ้นอยู่กับ JSDOM คุณสามารถลบ --env=jsdom
ได้อย่างปลอดภัยและการทดสอบของคุณจะทำงานได้เร็วขึ้น:
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
- "test": "react-scripts test --env=jsdom"
+ "test": "react-scripts test"
เพื่อช่วยให้คุณตัดสินใจได้นี่คือรายการ API ที่ ต้องการ JSDOM :
window
และ document
ReactDOM.render()
TestUtils.renderIntoDocument()
(ทางลัดสำหรับด้านบน)mount()
ในเอนไซม์ในทางตรงกันข้าม JSDOM ไม่จำเป็น สำหรับ APIs ต่อไปนี้:
TestUtils.createRenderer()
(การเรนเดอร์ตื้น)shallow()
ในเอนไซม์ในที่สุด JSDOM ก็ไม่จำเป็นสำหรับการทดสอบสแน็ปช็อต
การทดสอบสแน็ปช็อตเป็นคุณสมบัติของความตลกขบขันที่สร้างสแน็ปช็อตข้อความของส่วนประกอบของคุณโดยอัตโนมัติและบันทึกไว้ในดิสก์ดังนั้นหากเอาต์พุต UI เปลี่ยนไปคุณจะได้รับการแจ้งเตือนโดยไม่ต้องเขียนคำยืนยันใด ๆ เกี่ยวกับเอาต์พุตส่วนประกอบ อ่านเพิ่มเติมเกี่ยวกับการทดสอบสแน็ปช็อต
หากคุณใช้ Visual Studio Code มีส่วนขยายที่ตลกขบขันซึ่งทำงานร่วมกับ Create React App Out of the Box สิ่งนี้ให้คุณสมบัติที่มีลักษณะคล้าย IDE จำนวนมากในขณะที่ใช้ตัวแก้ไขข้อความ: แสดงสถานะของการทดสอบการทำงานด้วยข้อความที่ล้มเหลวในการเริ่มต้นและหยุดผู้เฝ้าดูโดยอัตโนมัติและเสนอการอัปเดตสแน็ปช็อตแบบคลิกเดียว
มีหลายวิธีในการตั้งค่าดีบักเกอร์สำหรับการทดสอบตลกของคุณ เราครอบคลุมการดีบักในรหัส Chrome และ Visual Studio
หมายเหตุ: การทดสอบการดีบักต้องใช้โหนด 8 หรือสูงกว่า
เพิ่มส่วนต่อไปนี้ในส่วน scripts
ใน package.json
โครงการของคุณ json
"scripts" : {
"test:debug" : " react-scripts --inspect-brk test --runInBand --env=jsdom "
}
Place debugger;
ข้อความในการทดสอบและการดำเนินการใด ๆ :
$ npm run test:debug
สิ่งนี้จะเริ่มเรียกใช้การทดสอบตลกของคุณ แต่หยุดชั่วคราวก่อนที่จะดำเนินการเพื่อให้ดีบักเกอร์แนบกับกระบวนการ
เปิดสิ่งต่อไปนี้ใน Chrome
about:inspect
หลังจากเปิดลิงค์นั้นเครื่องมือนักพัฒนา Chrome จะปรากฏขึ้น เลือก inspect
เกี่ยวกับกระบวนการของคุณและจุดพักจะถูกตั้งค่าที่บรรทัดแรกของสคริปต์ปฏิกิริยา (ทำเพื่อให้คุณมีเวลาในการเปิดเครื่องมือนักพัฒนาซอฟต์แวร์และเพื่อป้องกันไม่ให้ความตลกขบขันดำเนินการก่อนที่คุณจะมีเวลาทำ) คลิกปุ่มที่ดูเหมือนปุ่ม "เล่น" ที่ด้านขวาบนของหน้าจอเพื่อดำเนินการต่อ เมื่อ Jest ดำเนินการทดสอบที่มีคำสั่งดีบักเกอร์การดำเนินการจะหยุดชั่วคราวและคุณสามารถตรวจสอบขอบเขตปัจจุบันและสแต็กโทรได้
หมายเหตุ: -ตัวเลือก -รันนาบันด์ CLI ทำให้แน่ใจว่าการทดสอบ jest รันในกระบวนการเดียวกันแทนที่จะวางไข่สำหรับการทดสอบแต่ละครั้ง โดยปกติแล้ว jest ขนานการทดสอบจะทำงานข้ามกระบวนการ แต่มันยากที่จะดีบักกระบวนการหลายอย่างในเวลาเดียวกัน
การดีบักการทดสอบ jest ได้รับการสนับสนุนนอกกรอบสำหรับรหัส Visual Studio
ใช้ไฟล์การกำหนดค่า launch.json
ต่อไปนี้:
{
"version": "0.2.0",
"configurations": [
{
"name": "Debug CRA Tests",
"type": "node",
"request": "launch",
"runtimeExecutable": "${workspaceRoot}/node_modules/.bin/react-scripts",
"args": [
"test",
"--runInBand",
"--no-cache",
"--env=jsdom"
],
"cwd": "${workspaceRoot}",
"protocol": "inspector",
"console": "integratedTerminal",
"internalConsoleOptions": "neverOpen"
}
]
}
โดยปกติในแอพคุณมีส่วนประกอบ UI จำนวนมากและแต่ละรายการมีหลายรัฐ ตัวอย่างเช่นองค์ประกอบปุ่มง่าย ๆ อาจมีสถานะดังต่อไปนี้:
โดยปกติแล้วมันยากที่จะเห็นสถานะเหล่านี้โดยไม่ต้องใช้แอพตัวอย่างหรือตัวอย่าง
สร้างแอป React ไม่รวมเครื่องมือใด ๆ สำหรับสิ่งนี้โดยค่าเริ่มต้น แต่คุณสามารถเพิ่มนิทานสำหรับ React (Source) หรือ React Styleguidist (แหล่งที่มา) ลงในโครงการของคุณได้อย่างง่ายดาย เหล่านี้เป็นเครื่องมือของบุคคลที่สามที่ให้คุณพัฒนาส่วนประกอบและดูสถานะทั้งหมดของพวกเขาแยกออกจากแอพของคุณ
นอกจากนี้คุณยังสามารถปรับใช้หนังสือนิทานหรือสไตล์ของคุณเป็นแอพแบบคงที่ ด้วยวิธีนี้ทุกคนในทีมของคุณสามารถดูและตรวจสอบสถานะที่แตกต่างกันของส่วนประกอบ UI โดยไม่ต้องเริ่มต้นเซิร์ฟเวอร์แบ็กเอนด์หรือสร้างบัญชีในแอพของคุณ
นิทานเป็นสภาพแวดล้อมการพัฒนาสำหรับส่วนประกอบ UI ที่ตอบสนอง ช่วยให้คุณสามารถเรียกดูไลบรารีส่วนประกอบดูสถานะที่แตกต่างกันของแต่ละองค์ประกอบและพัฒนาและทดสอบส่วนประกอบแบบโต้ตอบ
ขั้นแรกให้ติดตั้งแพ็คเกจ NPM ต่อไปนี้ทั่วโลก:
npm install -g @storybook/cli
จากนั้นเรียกใช้คำสั่งต่อไปนี้ภายในไดเรกทอรีแอปของคุณ:
getstorybook
หลังจากนั้นให้ปฏิบัติตามคำแนะนำบนหน้าจอ
เรียนรู้เพิ่มเติมเกี่ยวกับ React Bookbook:
Styleguidist ผสมผสานคู่มือสไตล์ซึ่งส่วนประกอบทั้งหมดของคุณจะถูกนำเสนอในหน้าเดียวกับเอกสารประกอบฉากและตัวอย่างการใช้งานกับสภาพแวดล้อมสำหรับการพัฒนาส่วนประกอบที่แยกได้คล้ายกับนิทาน ใน Styleguidist คุณเขียนตัวอย่างใน Markdown ซึ่งแต่ละตัวอย่างรหัสจะแสดงเป็นสนามเด็กเล่นที่สามารถแก้ไขได้
ก่อนอื่นให้ติดตั้ง StyleGuidist:
npm install --save react-styleguidist
หรือคุณอาจใช้ yarn
:
yarn add react-styleguidist
จากนั้นเพิ่มสคริปต์เหล่านี้ลงใน package.json
ของคุณ json:
"scripts": {
+ "styleguide": "styleguidist server",
+ "styleguide:build": "styleguidist build",
"start": "react-scripts start",
จากนั้นเรียกใช้คำสั่งต่อไปนี้ภายในไดเรกทอรีแอปของคุณ:
npm run styleguide
หลังจากนั้นให้ปฏิบัติตามคำแนะนำบนหน้าจอ
เรียนรู้เพิ่มเติมเกี่ยวกับ React Styleguidist:
สร้างแอป React ไม่ได้ให้ฟังก์ชันการทำงานในตัวเพื่อเผยแพร่ส่วนประกอบไปยัง NPM หากคุณพร้อมที่จะดึงส่วนประกอบออกจากโครงการของคุณเพื่อให้คนอื่นสามารถใช้งานได้เราขอแนะนำให้ย้ายไปยังไดเรกทอรีแยกต่างหากนอกโครงการของคุณแล้วใช้เครื่องมือเช่น NWB เพื่อเตรียมการเผยแพร่
โดยค่าเริ่มต้นการสร้างการผลิตเป็นแอพพลิเคชั่นที่ใช้งานได้อย่างสมบูรณ์แบบออฟไลน์ก่อน
แอพพลิเคชั่นเว็บแบบก้าวหน้านั้นเร็วกว่าและเชื่อถือได้มากกว่าหน้าเว็บแบบดั้งเดิมและมอบประสบการณ์มือถือที่มีส่วนร่วม:
sw-precache-webpack-plugin
ถูกรวมเข้ากับการกำหนดค่าการผลิตและจะดูแลการสร้างไฟล์ผู้ปฏิบัติงานบริการที่จะตรวจสอบสินทรัพย์ท้องถิ่นทั้งหมดของคุณโดยอัตโนมัติ ผู้ปฏิบัติงานบริการจะใช้กลยุทธ์แคชครั้งแรกสำหรับการจัดการคำขอทั้งหมดสำหรับสินทรัพย์ในท้องถิ่นรวมถึง HTML เริ่มต้นเพื่อให้มั่นใจว่าแอปพลิเคชันเว็บของคุณรวดเร็วอย่างน่าเชื่อถือแม้ในเครือข่ายที่ช้าหรือไม่น่าเชื่อถือ
หากคุณไม่ต้องการเปิดใช้งานพนักงานบริการก่อนการปรับใช้การผลิตครั้งแรกของคุณให้ลบการโทรไปยัง registerServiceWorker()
จาก src/index.js
หากคุณเคยเปิดใช้งานพนักงานบริการในการปรับใช้การผลิตของคุณก่อนหน้านี้และได้ตัดสินใจว่าคุณต้องการปิดการใช้งานสำหรับผู้ใช้ที่มีอยู่ทั้งหมดของคุณคุณสามารถแลกเปลี่ยนการโทรไปยัง registerServiceWorker()
ใน src/index.js
ก่อน : :
import { unregister } from './registerServiceWorker' ;
จากนั้นเรียก unregister()
แทน หลังจากผู้ใช้เข้าชมหน้าเว็บที่ unregister()
ผู้ปฏิบัติงานบริการจะถูกถอนการติดตั้ง โปรดทราบว่าขึ้นอยู่กับวิธีการให้บริการ /service-worker.js
อาจใช้เวลานานถึง 24 ชั่วโมงสำหรับแคชที่จะไม่ถูกต้อง
พนักงานบริการต้องการ HTTPS แม้ว่าจะช่วยอำนวยความสะดวกในการทดสอบในท้องถิ่น แต่นโยบายนั้นไม่ได้ใช้กับ localhost
หากเว็บเซิร์ฟเวอร์การผลิตของคุณไม่รองรับ HTTPS การลงทะเบียนผู้ปฏิบัติงานบริการจะล้มเหลว แต่ส่วนที่เหลือของเว็บแอพของคุณจะยังคงใช้งานได้
พนักงานบริการไม่ได้รับการสนับสนุนในเว็บเบราว์เซอร์ทั้งหมด การลงทะเบียนผู้ปฏิบัติงานบริการจะไม่ถูกพยายามในเบราว์เซอร์ที่ขาดการสนับสนุน
ผู้ปฏิบัติงานบริการเปิดใช้งานเฉพาะในสภาพแวดล้อมการผลิตเช่นผลผลิตของ npm run build
ขอแนะนำให้คุณไม่เปิดใช้งานผู้ปฏิบัติงานบริการออฟไลน์ในสภาพแวดล้อมการพัฒนาเนื่องจากอาจนำไปสู่ความยุ่งยากเมื่อมีการใช้สินทรัพย์ที่แคชก่อนหน้านี้และไม่รวมถึงการเปลี่ยนแปลงล่าสุดที่คุณทำในท้องถิ่น
หากคุณ ต้องการ ทดสอบผู้ปฏิบัติงานบริการแบบออฟไลน์ก่อนในเครื่องให้สร้างแอปพลิเคชัน (โดยใช้ npm run build
) และเรียกใช้เซิร์ฟเวอร์ HTTP อย่างง่ายจากไดเรกทอรีบิลด์ของคุณ หลังจากเรียกใช้สคริปต์บิลด์ create-react-app
จะให้คำแนะนำสำหรับวิธีหนึ่งในการทดสอบการผลิตของคุณในพื้นที่และคำแนะนำการปรับใช้มีคำแนะนำสำหรับการใช้วิธีการอื่น อย่าลืมใช้หน้าต่างที่ไม่ระบุตัวตนเพื่อหลีกเลี่ยงภาวะแทรกซ้อนด้วยแคชเบราว์เซอร์ของคุณ
หากเป็นไปได้กำหนดค่าสภาพแวดล้อมการผลิตของคุณเพื่อให้บริการ service-worker.js
ที่สร้างขึ้น JS ด้วยการปิดการแคช HTTP หากเป็นไปไม่ได้-หน้า github ตัวอย่างเช่นไม่อนุญาตให้คุณเปลี่ยนอายุการใช้งานแคช HTTP 10 นาทีเริ่มต้น-จากนั้นโปรดทราบว่าถ้าคุณเยี่ยมชมไซต์การผลิตของคุณแล้วกลับมาอีกครั้งก่อนที่ service-worker.js
จะหมดอายุจากคุณ แคช HTTP คุณจะยังคงได้รับสินทรัพย์ที่แคชก่อนหน้านี้จากพนักงานบริการ หากคุณมีความต้องการทันทีในการดูการปรับใช้การผลิตที่อัปเดตของคุณการดำเนินการ Shift-refresh จะปิดการใช้งานผู้ปฏิบัติงานบริการชั่วคราวและดึงเนื้อหาทั้งหมดจากเครือข่าย
ผู้ใช้ไม่คุ้นเคยกับเว็บแอปออฟไลน์ก่อนเสมอ การแจ้งให้ผู้ใช้ทราบว่าเมื่อใดที่ผู้ปฏิบัติงานบริการได้เติมแคชของคุณเสร็จแล้ว (แสดงข้อความ "เว็บแอพนี้ทำงานออฟไลน์!") และแจ้งให้พวกเขาทราบเมื่อผู้ปฏิบัติงานบริการได้รับการอัปเดตล่าสุด ครั้งต่อไปที่พวกเขาโหลดหน้าเว็บ (แสดง "เนื้อหาใหม่พร้อมใช้งานโปรดรีเฟรช" ข้อความ) การแสดงข้อความนี้จะถูกทิ้งไว้เป็นแบบฝึกหัดให้กับนักพัฒนา แต่เป็นจุดเริ่มต้นคุณสามารถใช้ตรรกะที่รวมอยู่ใน src/registerServiceWorker.js
ซึ่งแสดงให้เห็นว่ากิจกรรม Lifecycle ของผู้ให้บริการที่จะตรวจจับแต่ละสถานการณ์และ ซึ่งเป็นค่าเริ่มต้นเพียงบันทึกข้อความที่เหมาะสมไปยังคอนโซล JavaScript
โดยค่าเริ่มต้นไฟล์ผู้ปฏิบัติงานบริการที่สร้างขึ้นจะไม่สกัดกั้นหรือแคชการรับส่งข้อมูลข้ามต้นใด ๆ เช่นคำขอ HTTP API รูปภาพหรือฝังที่โหลดจากโดเมนอื่น หากคุณต้องการใช้กลยุทธ์การแคชรันไทม์สำหรับคำขอเหล่านั้นคุณสามารถ eject
จากนั้นกำหนดค่าตัวเลือก runtimeCaching
ในส่วน SWPrecacheWebpackPlugin
ของ webpack.config.prod.js
การกำหนดค่าเริ่มต้นรวมถึงเว็บแอปที่แสดงอยู่ที่ public/manifest.json
ซึ่งคุณสามารถปรับแต่งด้วยรายละเอียดเฉพาะสำหรับเว็บแอปพลิเคชันของคุณ
เมื่อผู้ใช้เพิ่มเว็บแอพไปยังหน้าจอหลักโดยใช้ Chrome หรือ Firefox บน Android ข้อมูลเมตาใน manifest.json
จะกำหนดไอคอนชื่อและสีการสร้างแบรนด์ที่จะใช้เมื่อแอปพลิเคชันเว็บปรากฏขึ้น คู่มือ Web App Manifest ให้บริบทเพิ่มเติมเกี่ยวกับความหมายของแต่ละฟิลด์และวิธีการปรับแต่งของคุณจะส่งผลกระทบต่อประสบการณ์ของผู้ใช้ของคุณ
Source Map Explorer วิเคราะห์ JavaScript Bundles โดยใช้แผนที่แหล่งที่มา สิ่งนี้จะช่วยให้คุณเข้าใจว่าโค้ด bloat มาจากไหน
หากต้องการเพิ่ม Source Map Explorer ไปยังโครงการ Create React App ให้ทำตามขั้นตอนเหล่านี้:
npm install --save source-map-explorer
หรือคุณอาจใช้ yarn
:
yarn add source-map-explorer
จากนั้นใน package.json
ให้เพิ่มบรรทัดต่อไปนี้ใน scripts
:
"scripts": {
+ "analyze": "source-map-explorer build/static/js/main.*",
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test --env=jsdom",
จากนั้นเพื่อวิเคราะห์ชุดรวมการสร้างการผลิตจากนั้นเรียกใช้สคริปต์วิเคราะห์
npm run build
npm run analyze
npm run build
สร้างไดเรกทอรี build
ด้วยการสร้างแอปการผลิตของคุณ ตั้งค่าเซิร์ฟเวอร์ HTTP ที่คุณชื่นชอบเพื่อให้ผู้เข้าชมเว็บไซต์ของคุณเสิร์ฟ index.html
และขอเส้นทางคงที่เช่น /static/js/main.<hash>.js
เสิร์ฟพร้อมเนื้อหาของ /static/js/main.<hash>.js
ไฟล์
สำหรับสภาพแวดล้อมที่ใช้โหนดวิธีที่ง่ายที่สุดในการจัดการสิ่งนี้คือการติดตั้งให้บริการและปล่อยให้มันจัดการส่วนที่เหลือ:
npm install -g serve
serve -s build
คำสั่งสุดท้ายที่แสดงด้านบนจะให้บริการไซต์คงที่ของคุณบนพอร์ต 5000 เช่นเดียวกับการตั้งค่าภายในของเสิร์ฟหลายพอร์ตสามารถปรับได้โดยใช้ -p
หรือ --port
พอร์ตธง
เรียกใช้คำสั่งนี้เพื่อรับรายการตัวเลือกทั้งหมดที่มีอยู่:
serve -h
คุณไม่จำเป็นต้องใช้เซิร์ฟเวอร์แบบคงที่เพื่อเรียกใช้โครงการสร้างแอพสร้างปฏิกิริยาในการผลิต มันทำงานได้ดีเช่นเดียวกับการรวมเข้ากับไดนามิกที่มีอยู่
นี่คือตัวอย่างการเขียนโปรแกรมโดยใช้โหนดและ Express:
const express = require ( 'express' ) ;
const path = require ( 'path' ) ;
const app = express ( ) ;
app . use ( express . static ( path . join ( __dirname , 'build' ) ) ) ;
app . get ( '/' , function ( req , res ) {
res . sendFile ( path . join ( __dirname , 'build' , 'index.html' ) ) ;
} ) ;
app . listen ( 9000 ) ;
การเลือกซอฟต์แวร์เซิร์ฟเวอร์ของคุณก็ไม่สำคัญเช่นกัน เนื่องจากแอพสร้าง React เป็นแพลตฟอร์มที่ไม่เชื่อเรื่องพระเจ้าจึงไม่จำเป็นต้องใช้โหนดอย่างชัดเจน
โฟลเดอร์ build
ด์ที่มีสินทรัพย์คงที่เป็นเอาต์พุตเดียวที่ผลิตโดยแอพสร้างปฏิกิริยา
อย่างไรก็ตามสิ่งนี้ไม่เพียงพอหากคุณใช้การกำหนดเส้นทางฝั่งไคลเอ็นต์ อ่านส่วนถัดไปหากคุณต้องการสนับสนุน URL เช่น /todos/42
ในแอพหน้าเดียวของคุณ
If you use routers that use the HTML5 pushState
history API under the hood (for example, React Router with browserHistory
), many static file servers will fail. For example, if you used React Router with a route for /todos/42
, the development server will respond to localhost:3000/todos/42
properly, but an Express serving a production build as above will not.
This is because when there is a fresh page load for a /todos/42
, the server looks for the file build/todos/42
and does not find it. The server needs to be configured to respond to a request to /todos/42
by serving index.html
. For example, we can amend our Express example above to serve index.html
for any unknown paths:
app.use(express.static(path.join(__dirname, 'build')));
- app.get('/', function (req, res) {
+ app.get('/*', function (req, res) {
res.sendFile(path.join(__dirname, 'build', 'index.html'));
});
If you're using Apache HTTP Server, you need to create a .htaccess
file in the public
folder that looks like this:
Options -MultiViews
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.html [QSA,L]
It will get copied to the build
folder when you run npm run build
.
If you're using Apache Tomcat, you need to follow this Stack Overflow answer.
Now requests to /todos/42
will be handled correctly both in development and in production.
On a production build, and in a browser that supports service workers, the service worker will automatically handle all navigation requests, like for /todos/42
, by serving the cached copy of your index.html
. This service worker navigation routing can be configured or disabled by eject
ing and then modifying the navigateFallback
and navigateFallbackWhitelist
options of the SWPreachePlugin
configuration.
When users install your app to the homescreen of their device the default configuration will make a shortcut to /index.html
. This may not work for client-side routers which expect the app to be served from /
. Edit the web app manifest at public/manifest.json
and change start_url
to match the required URL scheme, for example:
"start_url" : "." ,
By default, Create React App produces a build assuming your app is hosted at the server root.
To override this, specify the homepage
in your package.json
, for example:
"homepage" : "http://mywebsite.com/relativepath" ,
This will let Create React App correctly infer the root path to use in the generated HTML file.
Note : If you are using react-router@^4
, you can root <Link>
s using the basename
prop on any <Router>
.
More information here.
ตัวอย่างเช่น:
< BrowserRouter basename = "/calendar" />
< Link to = "/today" / > // renders <a href="/calendar/today">
Note: this feature is available with
[email protected]
and higher.
If you are not using the HTML5 pushState
history API or not using client-side routing at all, it is unnecessary to specify the URL from which your app will be served. Instead, you can put this in your package.json
:
"homepage" : "." ,
This will make sure that all the asset paths are relative to index.html
. You will then be able to move your app from http://mywebsite.com
to http://mywebsite.com/relativepath
or even http://mywebsite.com/relative/path
without having to rebuild it.
See this blog post on how to deploy your React app to Microsoft Azure.
See this blog post or this repo for a way to use automatic deployment to Azure App Service.
Install the Firebase CLI if you haven't already by running npm install -g firebase-tools
. Sign up for a Firebase account and create a new project. Run firebase login
and login with your previous created Firebase account.
Then run the firebase init
command from your project's root. You need to choose the Hosting: Configure and deploy Firebase Hosting sites and choose the Firebase project you created in the previous step. You will need to agree with database.rules.json
being created, choose build
as the public directory, and also agree to Configure as a single-page app by replying with y
.
=== Project Setup
First, let ' s associate this project directory with a Firebase project.
You can create multiple project aliases by running firebase use --add,
but for now we ' ll just set up a default project.
? What Firebase project do you want to associate as default ? Example app (example-app-fd690)
=== Database Setup
Firebase Realtime Database Rules allow you to define how your data should be
structured and when your data can be read from and written to.
? What file should be used for Database Rules ? database.rules.json
✔ Database Rules for example-app-fd690 have been downloaded to database.rules.json.
Future modifications to database.rules.json will update Database Rules when you run
firebase deploy.
=== Hosting Setup
Your public directory is the folder (relative to your project directory) that
will contain Hosting assets to uploaded with firebase deploy. If you
have a build process for your assets, use your build ' s output directory.
? What do you want to use as your public directory? build
? Configure as a single-page app (rewrite all urls to /index.html)? Yes
✔ Wrote build/index.html
i Writing configuration info to firebase.json...
i Writing project information to .firebaserc...
✔ Firebase initialization complete!
IMPORTANT: you need to set proper HTTP caching headers for service-worker.js
file in firebase.json
file or you will not be able to see changes after first deployment (issue #2440). It should be added inside "hosting"
key like next:
{
"hosting": {
...
"headers": [
{"source": "/service-worker.js", "headers": [{"key": "Cache-Control", "value": "no-cache"}]}
]
...
Now, after you create a production build with npm run build
, you can deploy it by running firebase deploy
.
=== Deploying to ' example-app-fd690 ' ...
i deploying database, hosting
✔ database: rules ready to deploy.
i hosting: preparing build directory for upload...
Uploading: [ ============================== ] 75%✔ hosting: build folder uploaded successfully
✔ hosting: 8 files uploaded successfully
i starting release process (may take several minutes)...
✔ Deploy complete !
Project Console: https://console.firebase.google.com/project/example-app-fd690/overview
Hosting URL: https://example-app-fd690.firebaseapp.com
For more information see Add Firebase to your JavaScript Project.
Note: this feature is available with
[email protected]
and higher.
homepage
to package.json
The step below is important!
If you skip it, your app will not deploy correctly.
Open your package.json
and add a homepage
field for your project:
"homepage" : " https://myusername.github.io/my-app " ,
or for a GitHub user page:
"homepage" : " https://myusername.github.io " ,
Create React App uses the homepage
field to determine the root URL in the built HTML file.
gh-pages
and add deploy
to scripts
in package.json
Now, whenever you run npm run build
, you will see a cheat sheet with instructions on how to deploy to GitHub Pages.
To publish it at https://myusername.github.io/my-app, run:
npm install --save gh-pages
Alternatively you may use yarn
:
yarn add gh-pages
Add the following scripts in your package.json
:
"scripts": {
+ "predeploy": "npm run build",
+ "deploy": "gh-pages -d build",
"start": "react-scripts start",
"build": "react-scripts build",
The predeploy
script will run automatically before deploy
is run.
If you are deploying to a GitHub user page instead of a project page you'll need to make two additional modifications:
package.json
scripts to push deployments to master : "scripts": {
"predeploy": "npm run build",
- "deploy": "gh-pages -d build",
+ "deploy": "gh-pages -b master -d build",
npm run deploy
Then run:
npm run deploy
gh-pages
Finally, make sure GitHub Pages option in your GitHub project settings is set to use the gh-pages
branch:
You can configure a custom domain with GitHub Pages by adding a CNAME
file to the public/
folder.
GitHub Pages doesn't support routers that use the HTML5 pushState
history API under the hood (for example, React Router using browserHistory
). This is because when there is a fresh page load for a url like http://user.github.io/todomvc/todos/42
, where /todos/42
is a frontend route, the GitHub Pages server returns 404 because it knows nothing of /todos/42
. If you want to add a router to a project hosted on GitHub Pages, here are a couple of solutions:
hashHistory
for this effect, but the URL will be longer and more verbose (for example, http://user.github.io/todomvc/#/todos/42?_k=yknaj
) . Read more about different history implementations in React Router.index.html
page with a special redirect parameter. You would need to add a 404.html
file with the redirection code to the build
folder before deploying your project, and you'll need to add code handling the redirect parameter to index.html
. You can find a detailed explanation of this technique in this guide. Use the Heroku Buildpack for Create React App.
You can find instructions in Deploying React with Zero Configuration.
Sometimes npm run build
works locally but fails during deploy via Heroku. Following are the most common cases.
If you get something like this:
remote: Failed to create a production build. Reason:
remote: Module not found: Error: Cannot resolve 'file' or 'directory'
MyDirectory in /tmp/build_1234/src
It means you need to ensure that the lettercase of the file or directory you import
matches the one you see on your filesystem or on GitHub.
This is important because Linux (the operating system used by Heroku) is case sensitive. So MyDirectory
and mydirectory
are two distinct directories and thus, even though the project builds locally, the difference in case breaks the import
statements on Heroku remotes.
If you exclude or ignore necessary files from the package you will see a error similar this one:
remote: Could not find a required file.
remote: Name: `index.html`
remote: Searched in: /tmp/build_a2875fc163b209225122d68916f1d4df/public
remote:
remote: npm ERR! Linux 3.13.0-105-generic
remote: npm ERR! argv "/tmp/build_a2875fc163b209225122d68916f1d4df/.heroku/node/bin/node" "/tmp/build_a2875fc163b209225122d68916f1d4df/.heroku/node/bin/npm" "run" "build"
In this case, ensure that the file is there with the proper lettercase and that's not ignored on your local .gitignore
or ~/.gitignore_global
.
To do a manual deploy to Netlify's CDN:
npm install netlify-cli -g
netlify deploy
Choose build
as the path to deploy.
To setup continuous delivery:
With this setup Netlify will build and deploy when you push to git or open a pull request:
yarn build
as the build command and build
as the publish directoryDeploy site
Support for client-side routing:
To support pushState
, make sure to create a public/_redirects
file with the following rewrite rules:
/* /index.html 200
When you build the project, Create React App will place the public
folder contents into the build output.
Now offers a zero-configuration single-command deployment. You can use now
to deploy your app for free.
Install the now
command-line tool either via the recommended desktop tool or via node with npm install -g now
.
Build your app by running npm run build
.
Move into the build directory by running cd build
.
Run now --name your-project-name
from within the build directory. You will see a now.sh URL in your output like this:
> Ready! https://your-project-name-tpspyhtdtk.now.sh (copied to clipboard)
Paste that URL into your browser when the build is complete, and you will see your deployed app.
Details are available in this article.
See this blog post on how to deploy your React app to Amazon Web Services S3 and CloudFront.
Install the Surge CLI if you haven't already by running npm install -g surge
. Run the surge
command and log in you or create a new account.
When asked about the project path, make sure to specify the build
folder, for example:
project path: /path/to/project/build
Note that in order to support routers that use HTML5 pushState
API, you may want to rename the index.html
in your build folder to 200.html
before deploying to Surge. This ensures that every URL falls back to that file.
You can adjust various development and production settings by setting environment variables in your shell or with .env.
ตัวแปร | การพัฒนา | การผลิต | การใช้งาน |
---|---|---|---|
BROWSER | By default, Create React App will open the default system browser, favoring Chrome on macOS. Specify a browser to override this behavior, or set it to none to disable it completely. If you need to customize the way the browser is launched, you can specify a node script instead. Any arguments passed to npm start will also be passed to this script, and the url where your app is served will be the last argument. Your script's file name must have the .js extension. | ||
เจ้าภาพ | By default, the development web server binds to localhost . You may use this variable to specify a different host. | ||
ท่าเรือ | By default, the development web server will attempt to listen on port 3000 or prompt you to attempt the next available port. You may use this variable to specify a different port. | ||
HTTPS | When set to true , Create React App will run the development server in https mode. | ||
PUBLIC_URL | Create React App assumes your application is hosted at the serving web server's root or a subpath as specified in package.json ( homepage ). Normally, Create React App ignores the hostname. You may use this variable to force assets to be referenced verbatim to the url you provide (hostname included). This may be particularly useful when using a CDN to host your application. | ||
ซีไอ | - | When set to true , Create React App treats warnings as failures in the build. It also makes the test runner non-watching. Most CIs set this flag by default. | |
REACT_EDITOR | When an app crashes in development, you will see an error overlay with clickable stack trace. When you click on it, Create React App will try to determine the editor you are using based on currently running processes, and open the relevant source file. You can send a pull request to detect your editor of choice. Setting this environment variable overrides the automatic detection. If you do it, make sure your systems PATH environment variable points to your editor's bin folder. You can also set it to none to disable it completely. | ||
CHOKIDAR_USEPOLLING | When set to true , the watcher runs in polling mode, as necessary inside a VM. Use this option if npm start isn't detecting changes. | ||
GENERATE_SOURCEMAP | When set to false , source maps are not generated for a production build. This solves OOM issues on some smaller machines. | ||
NODE_PATH | Same as NODE_PATH in Node.js, but only relative folders are allowed. Can be handy for emulating a monorepo setup by setting NODE_PATH=src . |
npm start
doesn't detect changes When you save a file while npm start
is running, the browser should refresh with the updated code.
If this doesn't happen, try one of the following workarounds:
index.js
and you're referencing it by the folder name, you need to restart the watcher due to a Webpack bug..env
file in your project directory if it doesn't exist, and add CHOKIDAR_USEPOLLING=true
to it. This ensures that the next time you run npm start
, the watcher uses the polling mode, as necessary inside a VM.If none of these solutions help please leave a comment in this thread.
npm test
hangs on macOS Sierra If you run npm test
and the console gets stuck after printing react-scripts test --env=jsdom
to the console there might be a problem with your Watchman installation as described in facebookincubator/create-react-app#713.
We recommend deleting node_modules
in your project and running npm install
(or yarn
if you use it) first. If it doesn't help, you can try one of the numerous workarounds mentioned in these issues:
It is reported that installing Watchman 4.7.0 or newer fixes the issue. If you use Homebrew, you can run these commands to update it:
watchman shutdown-server
brew update
brew reinstall watchman
You can find other installation methods on the Watchman documentation page.
If this still doesn't help, try running launchctl unload -F ~/Library/LaunchAgents/com.github.facebook.watchman.plist
.
There are also reports that uninstalling Watchman fixes the issue. So if nothing else helps, remove it from your system and try again.
npm run build
exits too early It is reported that npm run build
can fail on machines with limited memory and no swap space, which is common in cloud environments. Even with small projects this command can increase RAM usage in your system by hundreds of megabytes, so if you have less than 1 GB of available memory your build is likely to fail with the following message:
The build failed because the process exited too early. This probably means the system ran out of memory or someone called
kill -9
on the process.
If you are completely sure that you didn't terminate the process, consider adding some swap space to the machine you're building on, or build the project locally.
npm run build
fails on HerokuThis may be a problem with case sensitive filenames. Please refer to this section.
If you use a Moment.js, you might notice that only the English locale is available by default. This is because the locale files are large, and you probably only need a subset of all the locales provided by Moment.js.
To add a specific Moment.js locale to your bundle, you need to import it explicitly.
ตัวอย่างเช่น:
import moment from 'moment' ;
import 'moment/locale/fr' ;
If import multiple locales this way, you can later switch between them by calling moment.locale()
with the locale name:
import moment from 'moment' ;
import 'moment/locale/fr' ;
import 'moment/locale/es' ;
// ...
moment . locale ( 'fr' ) ;
This will only work for locales that have been explicitly imported before.
npm run build
fails to minifySome third-party packages don't compile their code to ES5 before publishing to npm. This often causes problems in the ecosystem because neither browsers (except for most modern versions) nor some tools currently support all ES6 features. We recommend to publish code on npm as ES5 at least for a few more years.
module
field in package.json
. Note that even if a library provides an ES Modules version, it should still precompile other ES6 features to ES5 if it intends to support older browsers .Fork the package and publish a corrected version yourself.
If the dependency is small enough, copy it to your src/
folder and treat it as application code.
In the future, we might start automatically compiling incompatible third-party modules, but it is not currently supported. This approach would also slow down the production builds.
Ejecting lets you customize anything, but from that point on you have to maintain the configuration and scripts yourself. This can be daunting if you have many similar projects. In such cases instead of ejecting we recommend to fork react-scripts
and any other packages you need. This article dives into how to do it in depth. You can find more discussion in this issue.
If you have ideas for more “How To” recipes that should be on this page, let us know or contribute some!