นี่คือโซลูชันการจัดการระดับกลางและแบ็กเอนด์ที่ใช้ React+React-router4+an�td3
โซลูชันระดับกลางและแบ็คเอนด์ที่ใช้ React+react-router+antd พร้อมใช้งานทันทีเมื่อแกะกล่อง โดยไม่มีการกำหนดค่าใดๆ และเพียงแค่บำรุงรักษา json
โปรเจ็กต์นี้บูทด้วย 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
ได้ เพื่อการสร้างใหม่ที่รวดเร็วยิ่งขึ้น เฉพาะไฟล์ภายใน src
เท่านั้นที่จะถูกประมวลผลโดย Webpack
คุณต้อง ใส่ไฟล์ 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 และอาจไม่ทำงานหากไม่มี polyfill หากมีข้อสงสัย ให้ใช้ Babel REPL เพื่อดูว่ามีอะไรบ้าง ไวยากรณ์เฉพาะใด ๆ ที่คอมไพล์ลงไปที่
หากต้องการกำหนดค่าการเน้นไวยากรณ์ในโปรแกรมแก้ไขข้อความที่คุณชื่นชอบ ให้ไปที่หน้าเอกสาร Babel ที่เกี่ยวข้องและทำตามคำแนะนำ
หมายเหตุ: คุณลักษณะนี้ใช้ได้กับ
[email protected]
และสูงกว่า
นอกจากนี้ยังใช้งานได้กับ npm 3 หรือสูงกว่าเท่านั้น
โปรแกรมแก้ไขบางส่วน รวมถึง Sublime Text, Atom และ Visual Studio Code มีปลั๊กอินสำหรับ ESLint
ไม่จำเป็นสำหรับการเป็นขุย คุณควรเห็นเอาต์พุตของ linter ในเทอร์มินัลของคุณเช่นเดียวกับคอนโซลของเบราว์เซอร์ อย่างไรก็ตาม หากคุณต้องการให้ผลลัพธ์ของขุยปรากฏในโปรแกรมแก้ไขของคุณ ก็มีขั้นตอนเพิ่มเติมที่คุณสามารถทำได้
คุณจะต้องติดตั้งปลั๊กอิน ESLint สำหรับโปรแกรมแก้ไขของคุณก่อน จากนั้น เพิ่มไฟล์ชื่อ .eslintrc
ไปที่รูทโปรเจ็กต์:
{
"extends" : "react-app"
}
ตอนนี้บรรณาธิการของคุณควรรายงานคำเตือนที่เป็นขุย
โปรดทราบว่าแม้ว่าคุณจะแก้ไขไฟล์ .eslintrc
เพิ่มเติม การเปลี่ยนแปลงเหล่านี้จะ ส่งผลต่อการรวมตัวแก้ไขเท่านั้น โดยจะไม่ส่งผลกระทบต่อเทอร์มินัลและเอาต์พุต Lint ในเบราว์เซอร์ เนื่องจากแอป 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...
จาก http://localhost:3000
คลิก +
และเลือก JavaScript Debug
หมายเหตุ: 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
ช่วยให้เราสามารถรันสคริปต์บนไฟล์ 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 เป็นการขึ้น 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
ของคุณ โดยทั่วไปแนวทางปฏิบัติที่ดีคือให้ผลิตภัณฑ์บิลด์อยู่นอกการควบคุมแหล่งที่มา
ในขั้นตอนสุดท้าย คุณอาจพบว่าสะดวกในการรัน 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 รวมไฟล์นั้นไว้ในบันเดิล การนำเข้าไฟล์จะให้ค่าสตริงแก่คุณ แอตทริบิวต์ src
ของรูปภาพหรือ href
ของลิงก์ไปยัง PDF
เพื่อลดจำนวนคำขอไปยังเซิร์ฟเวอร์ การนำเข้ารูปภาพที่มีขนาดน้อยกว่า 10,000 ไบต์จะส่งคืน URI ข้อมูลแทนเส้นทาง ซึ่งใช้กับนามสกุลไฟล์ต่อไปนี้: ไฟล์ bmp, gif, jpg, jpeg และ png เนื่องจาก #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 จะย้ายรูปภาพไปยังโฟลเดอร์ build อย่างถูกต้อง และให้เส้นทางที่ถูกต้องแก่เรา
สิ่งนี้ใช้ได้กับ 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 จะ ไม่ ประมวลผลไฟล์นั้นจะถูกคัดลอกไปยังโฟลเดอร์บิลด์โดยไม่ถูกแตะต้อง หากต้องการอ้างอิงเนื้อหาในโฟลเดอร์ 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 ได้โดยทำตามขั้นตอนเหล่านี้:
ติดตั้ง 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
และแทนที่ด้วยตัวอย่างใดๆ บนเว็บไซต์ The Basic Example ถือเป็นจุดเริ่มต้นที่ดี
โปรดทราบว่าคุณอาจต้องกำหนดค่าเซิร์ฟเวอร์ที่ใช้งานจริงให้รองรับการกำหนดเส้นทางฝั่งไคลเอ็นต์ก่อนที่จะปรับใช้แอปของคุณ
หมายเหตุ: คุณลักษณะนี้ใช้ได้กับ
[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 และ/หรือแพลตฟอร์มโฮสติ้งของคุณก็มักจะต้องมีการกำหนดตัวแปรเหล่านี้เช่นกัน ศึกษาเอกสารประกอบของพวกเขาเกี่ยวกับวิธีการทำเช่นนี้
.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 หรือ fetch()
fetch()
ที่จัดทำโดยเบราว์เซอร์ กังวลเกี่ยวกับการสนับสนุนเบราว์เซอร์
ฟัง Promise
ชั่น fetch
ทั่วโลกช่วยให้สามารถ Response
fetch
ได้อย่างง่ายดาย
โครงการนี้ยังรวมถึงสัญญา Polyfill ซึ่งให้การดำเนินการอย่างเต็มรูปแบบของสัญญา/ fetch()
+ . คุณยังสามารถใช้ไวยากรณ์ async / await
เพื่อลดการทำรังการโทรกลับ
คุณสามารถเรียนรู้เพิ่มเติมเกี่ยวกับการทำคำขอ AJAX จากส่วนประกอบ React ในรายการคำถามที่พบบ่อยในเว็บไซต์ React
บทเรียนเหล่านี้จะช่วยให้คุณรวมแอปของคุณเข้ากับแบ็กเอนด์ API ที่ทำงานบนพอร์ตอื่นโดยใช้ fetch()
เพื่อเข้าถึง
ตรวจสอบบทช่วยสอนนี้
ตรวจสอบบทช่วยสอนนี้
หมายเหตุ: คุณลักษณะนี้สามารถใช้ได้กับ
[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
) และขึ้นอยู่กับคุณเพื่อให้แน่ใจ /api
URL เช่น /api/todos
ชี้ไปที่สิ่งที่ถูกต้องในการผลิต . คำขอใด ๆ ที่ไม่รู้จักโดยไม่มี text/html
ที่ยอมรับจะถูกเปลี่ยนเส้นทางไปยัง proxy
ที่ระบุ
ตัวเลือก proxy
รองรับการเชื่อมต่อ HTTP, HTTPS และ WebSocket
หากตัวเลือก proxy
ไม่ ยืดหยุ่นเพียงพอสำหรับคุณหรือคุณสามารถ:
เมื่อคุณเปิดใช้งานตัวเลือก proxy
คุณจะเลือกชุดการตรวจสอบโฮสต์ที่เข้มงวดมากขึ้น
สิ่งนี้ไม่ควรส่งผลกระทบต่อคุณเมื่อพัฒนาใน 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
// ...
}
}
// ...
}
คำขอทั้งหมดที่จับคู่เส้นทางนี้ proxy
เป็นพร็อกซีไม่มี text/html
ยกเว้น
หากคุณต้องการระบุพร็อกซีหลายตัวคุณสามารถทำได้โดยการระบุรายการเพิ่มเติม
{
// ...
"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 Engine เช่น Socket.io คุณต้องมีเซิร์ฟเวอร์ Socket.io ที่คุณสามารถใช้เป็นเป้าหมายพร็อกซีได้ .IO เพื่อทำงานกับการทดสอบ echo websocket.org echo
มีเอกสารที่ดีสำหรับการตั้งค่า Socket.io Server
WebSockets มาตรฐาน จะ ทำงานกับเซิร์ฟเวอร์ WebSocket มาตรฐานรวมถึงการทดสอบ echo websocket.org Echo
ไม่ว่าจะด้วยวิธีใดคุณสามารถร้องขอพร็อกซี 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
ในการทำเช่นนี้ให้ตั้งค่าตัวแปรสภาพแวดล้อม HTTPS
เป็น true
จากนั้นเริ่มเซิร์ฟเวอร์ dev ตามปกติด้วย npm start
:
set HTTPS = true && npm start
( $ env: HTTPS = $true ) -and (npm start)
(หมายเหตุ: การขาดช่องว่างเป็นความตั้งใจ)
HTTPS=true npm start
โปรดทราบว่าเซิร์ฟเวอร์จะใช้ใบรับรองที่ลงนามด้วยตนเองดังนั้นเว็บเบราว์เซอร์ของคุณจะแสดงคำเตือนเมื่อเข้าถึงหน้าเว็บได้อย่างแน่นอน
<meta>
บนเซิร์ฟเวอร์ เนื่องจากแอป React ไม่รองรับการเรนเดอร์เซิร์ฟเวอร์คุณอาจสงสัยว่าจะสร้างแท็ก <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
แอพของคุณเสี่ยงต่อการโจมตี XSS
หมายเหตุ: คุณลักษณะนี้มีให้เลือกด้วย
[email protected]
และสูงกว่า
อ่านคู่มือการโยกย้ายเพื่อเรียนรู้วิธีเปิดใช้งานในโครงการเก่า!
สร้างแอป React ใช้ Jest เป็นนักวิ่งทดสอบ
Jest เป็นนักวิ่งที่ใช้โหนด
ในขณะที่ jest ให้รอบเบราว์เซอร์เช่น window
ขอบคุณ JSDOM พวกเขาเป็นเพียงการประมาณของพฤติกรรมเบราว์เซอร์จริง
เราขอแนะนำให้คุณใช้เครื่องมือแยกต่างหากสำหรับการทดสอบแบบครบวงจรของเบราว์เซอร์หากคุณต้องการ
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'
แทนที่จะเป็นเส้นทางที่ยาวนาน
เมื่อคุณเรียกใช้ npm test
Jest จะเปิดตัว npm start
โหมดนาฬิกา
ผู้เฝ้าดูรวมถึงอินเทอร์เฟซบรรทัดคำสั่งแบบโต้ตอบที่มีความสามารถในการเรียกใช้การทดสอบทั้งหมดหรือมุ่งเน้นไปที่รูปแบบการค้นหา “ ดูการใช้งาน” โปรดทราบว่าผู้เฝ้าดูพิมพ์หลังจากการวิ่งทุกครั้ง:
โดยค่าเริ่มต้นเมื่อคุณเรียกใช้ npm test
JEST จะเรียกใช้การทดสอบที่เกี่ยวข้องกับไฟล์ที่เปลี่ยนแปลงไปตั้งแต่การประชุมครั้งสุดท้าย มักจะใช้รหัสที่ไม่ผ่านการทดสอบ
JEST จะพูดถึงอย่างชัดเจนว่ามันมีเพียงการทดสอบที่เกี่ยวข้องกับไฟล์ที่เปลี่ยนแปลงไปตั้งแต่ a
กระทำครั้งสุดท้าย
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()
API จากเอนไซม์
npm install --save enzyme enzyme-adapter-react-16 react-test-renderer
หรือคุณอาจใช้ yarn
:
yarn add enzyme enzyme-adapter-react-16 react-test-renderer
ในฐานะที่เป็นเอนไซม์ 3 คุณจะต้องติดตั้งเอนไซม์พร้อมกับอะแดปเตอร์ที่สอดคล้องกับเวอร์ชันของปฏิกิริยาที่คุณใช้
อะแดปเตอร์จะต้องกำหนดค่าในไฟล์การตั้งค่าส่วนกลางของคุณ:
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 /> ) ;
} ) ;
การทดสอบนี้แตกต่างจากการทดสอบควันก่อนหน้านี้โดย <Button>
reactdom.render <App>
ReactDOM.render()
การทดสอบนี้จะแสดงผลเฉพาะ <App>
และไม่ลึกลงไป เป็นสิ่งที่ดีสำหรับการทดสอบหน่วยที่แยกได้ แต่คุณอาจต้องการสร้างการทดสอบการเรนเดอร์เต็มรูป mount()
เพื่อให้แน่ใจว่าส่วนประกอบรวมเข้าด้วยกันอย่างถูกต้อง
คุณสามารถอ่านเอกสารประกอบ jest.fn()
เอนไซม์ expect()
เทคนิคการทดสอบเพิ่มเติม
นี่คือตัวอย่างจากเอกสารของเอนไซม์ที่ยืนยันผลลัพธ์ที่เฉพาะเจาะจงเขียนใหม่เพื่อใช้ 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 ) ;
} ) ;
ผู้จับคู่ที่ตลกขบขันทั้งหมดได้รับการบันทึกไว้อย่างกว้างขวางที่นี่
อย่างไรก็ตามคุณสามารถใช้ห้องสมุดการยืนยันบุคคลที่สามเช่นชัยถ้าคุณต้องการตามที่อธิบายไว้ด้านล่าง
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 " ]
}
}
โดยค่าเริ่มต้นการ CI
npm test
เรียกใช้ Watcher ด้วย Interactive CLI
เมื่อสร้างแอปพลิเคชันของคุณด้วย npm test
npm run build
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 เริ่มต้นและหยุดผู้เฝ้าดูโดยอัตโนมัติและเสนอการอัปเดตสแน็ปช็อตแบบคลิกเดียว
มีหลายวิธีในการตั้งค่าดีบักเกอร์สำหรับการทดสอบความตลกขบขันของคุณ
หมายเหตุ: การทดสอบการดีบักต้องใช้โหนด 8 หรือสูงกว่า
เพิ่มส่วนต่อไปนี้ในส่วน scripts
ใน package.json
โครงการของคุณ json
"scripts" : {
"test:debug" : " react-scripts --inspect-brk test --runInBand --env=jsdom "
}
วาง debugger;
$ npm run test:debug
สิ่งนี้จะเริ่มเรียกใช้การทดสอบตลกของคุณ แต่หยุดชั่วคราวก่อนที่จะดำเนินการเพื่อให้ดีบักเกอร์แนบกับกระบวนการ
เปิดสิ่งต่อไปนี้ใน Chrome
about:inspect
หลังจากเปิดลิงก์นั้นเครื่องมือนักพัฒนา Chrome จะปรากฏ inspect
จากการดำเนินการก่อนที่คุณจะมีเวลาทำ) คุณสามารถตรวจสอบขอบเขตและการโทรปัจจุบันได้ สแต็ค
หมายเหตุ: ตัวเลือก -รันจันไล่ออก CLI ทำให้แน่ใจว่าการทดสอบการทำงานของ JEST ในกระบวนการเดียวกันแทนที่จะเป็นกระบวนการวางไข่สำหรับการทดสอบแต่ละครั้ง
การดีบักการทดสอบ jest ได้รับการสนับสนุนนอกกรอบสำหรับรหัสสตูดิโอ Visual
ใช้ไฟล์การกำหนดค่า 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 ที่ตอบสนอง
ขั้นแรกให้ติดตั้งแพ็คเกจ NPM ต่อไปนี้ทั่วโลก:
npm install -g @storybook/cli
จากนั้นเรียกใช้คำสั่งต่อไปนี้ภายในไดเรกทอรีแอปของคุณ:
getstorybook
หลังจากนั้นให้ทำตามคำแนะนำบนหน้าจอ
เรียนรู้เพิ่มเติมเกี่ยวกับ React Bookbook:
Styleguidist รวมคู่มือสไตล์ที่ส่วนประกอบทั้งหมดของคุณจะถูกนำเสนอในหน้าเดียวกับเอกสารประกอบฉากและตัวอย่างการใช้งานกับสภาพแวดล้อมสำหรับการพัฒนาส่วนประกอบที่แยกได้คล้ายกับนิทาน แสดงเป็นสนามเด็กเล่นที่สามารถแก้ไขได้
ก่อนอื่นให้ติดตั้ง 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()
/service-worker.js
unregister()
แคชที่จะไม่ถูกต้อง
พนักงานบริการต้องการ HTTPS แม้ว่าจะอำนวยความสะดวกในการทดสอบในท้องถิ่น แต่นโยบายนั้นไม่ได้ใช้กับ localhost
ขณะนี้พนักงานบริการไม่ได้รับการสนับสนุนในเว็บเบราว์เซอร์ทั้งหมด
ผู้ปฏิบัติงานบริการเปิดใช้งานเฉพาะในสภาพแวดล้อมการผลิตเช่นการสร้าง npm run build
อย่ารวมการเปลี่ยนแปลงล่าสุดที่คุณทำในท้องถิ่น
หากคุณ ต้องการ ทดสอบผู้ปฏิบัติงานบริการออฟไลน์แรกของคุณในเครื่องให้สร้างแอปพลิ create-react-app
(โดยใช้ npm run build
) และเรียกใช้เซิร์ฟเวอร์ HTTP อย่างง่ายจากไดเรกทอรี Build ของคุณ เพื่อทดสอบการผลิตของคุณในพื้นที่ และ คำแนะนำการปรับใช้มีคำแนะนำสำหรับการใช้วิธีการอื่น ๆ
หากเป็นไปได้ให้กำหนดค่าสภาพแวดล้อมการผลิตของคุณเพื่อให้บริการ service-worker.js
ที่สร้างขึ้นด้วยการปิดการแคช HTTP หากคุณเยี่ยมชมเว็บไซต์การผลิตของคุณแล้วกลับมาอีกครั้งก่อนที่ service-worker.js
จะหมดอายุจากแคช HTTP ของคุณคุณจะยังคงได้รับสินทรัพย์ที่แคชก่อนหน้านี้จากพนักงานบริการ การปรับใช้ การดำเนินการ Shift-refresh จะปิดการใช้งานผู้ปฏิบัติงานบริการชั่วคราวและดึงสินทรัพย์ทั้งหมดจากเครือข่าย
ผู้ใช้ไม่คุ้นเคยกับเว็บแอปออฟไลน์ก่อนเสมอ ผู้ปฏิบัติงานบริการได้ดึงข้อมูลการอัปเดตล่าสุดที่จะพร้อมใช้งานในครั้งต่อไปที่พวกเขาโหลดหน้าเว็บ (แสดง "เนื้อหาใหม่พร้อมใช้งานโปรดรีเฟรช" จุดเริ่มต้นคุณสามารถใช้ประโยชน์ได้ ตรรกะที่รวมอยู่ใน src/registerServiceWorker.js
ซึ่งแสดงให้เห็นว่าเหตุการณ์วงจรชีวิตผู้ปฏิบัติงานบริการใดที่จะฟังเพื่อตรวจจับแต่ละสถานการณ์และเป็นค่าเริ่มต้นเพียงบันทึกข้อความที่เหมาะสมไปยังคอนโซล JavaScript
โดยค่าเริ่มต้นไฟล์ผู้ปฏิบัติงานบริการที่สร้างขึ้นจะไม่สกัดกั้นหรือแคชการรับส่งข้อมูลข้ามต้นใด ๆ เช่นคำขอ HTTP API รูปภาพหรือฝังที่โหลดจากโดเมนอื่น eject
แล้วกำหนดค่าตัวเลือก runtimeCaching
ในส่วน SWPrecacheWebpackPlugin
ของ webpack.config.prod.js
การกำหนดค่าเริ่มต้นรวมถึงเว็บแอปที่แสดงอยู่ที่ public/manifest.json
ซึ่งคุณสามารถปรับแต่งด้วยรายละเอียดเฉพาะสำหรับเว็บแอปพลิเคชันของคุณ
เมื่อผู้ใช้เพิ่มเว็บแอพไปยังหน้าจอหลักโดยใช้ Chrome หรือ Firefox บน Android ข้อมูลเมตาใน manifest.json
จะกำหนดไอคอนชื่อและสีการสร้างแบรนด์ที่จะใช้เมื่อแอปพลิเคชันเว็บปรากฏขึ้น ความหมายของแต่ละฟิลด์และวิธีการปรับแต่งของคุณจะส่งผลต่อประสบการณ์ของผู้ใช้ของคุณ
Source Map Explorer JavaScript Bundles โดยใช้แผนที่แหล่งที่มา
หากต้องการเพิ่ม 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
index.html
ไดเรกทอรี build
ด้วยการสร้างแอ /static/js/main.<hash>.js
ของคุณ /static/js/main.<hash>.js
เสิร์ฟพร้อมเนื้อหาของไฟล์ /static/js/main.<hash>.js
สำหรับสภาพแวดล้อมที่ใช้โหนดวิธีที่ง่ายที่สุดในการจัดการสิ่งนี้คือการติดตั้งให้บริการและปล่อยให้มันจัดการส่วนที่เหลือ:
npm install -g serve
serve -s build
คำสั่งสุดท้ายที่แสดงด้านบนจะให้บริการไซต์คงที่ของคุณบนพอร์ต 5000 เช่นเดียวกับการตั้งค่าภายในของ Serves หลายพอร์ตสามารถปรับได้โดยใช้ -p
หรือ --port
พอร์ตธง
เรียกใช้คำสั่งนี้เพื่อรับรายการตัวเลือกทั้งหมดที่มีอยู่:
serve -h
คุณไม่จำเป็นต้องใช้เซิร์ฟเวอร์แบบคงที่เพื่อเรียกใช้โครงการสร้างแอป React ในการผลิต
นี่คือตัวอย่างการเขียนโปรแกรมโดยใช้โหนดและ 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 ) ;
การเลือกซอฟต์แวร์เซิร์ฟเวอร์ของคุณไม่สำคัญเช่นกัน
โฟลเดอร์ build
ด์ที่มีสินทรัพย์คงที่เป็นเอาต์พุตเดียวที่ผลิตโดยแอพสร้างปฏิกิริยา
อย่างไรก็ตามสิ่งนี้ไม่เพียงพอหากคุณใช้การกำหนดเส้นทางฝั่ง /todos/42
หากคุณใช้เราเตอร์ที่ใช้ HTML5 pushState
History API ภายใต้ฮูด (ตัวอย่างเช่นเราเตอร์ตอบสนองด้วยเบราว์ browserHistory
) เซิร์ฟเวอร์ไฟล์ /todos/42
ที่จำนวนมากจะล้มเหลว 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 ต่อไป:
{
"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 อย่างสมบูรณ์. | ||
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
ล้มเหลวในการลดขนาดSome 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!