筆者最近打算基於半年來的實踐與React社區的發展重製下筆者的React系列教程,前端實戰文章——React系列。本文從屬於Web 前端入門與最佳實踐。css
create-react-app是來自於Facebook出品的零配置命令行工具,可以幫你自動建立基於Webpack+ES6的最簡易的React項目模板,有助於初學者快速上手實踐。安裝create-react-app的方式也很是簡單,能夠直接使用npm
命令進行全局安裝。html
npm install -g create-react-app create-react-app my-app cd my-app/ npm start
執行完上述命令以後,你能夠直接打開http://localhost:3000
,便可以看到你React APP的運行效果。此時也是處於開發模式下,若是你要進行發佈,則使用npm run build
進行編譯。前端
create-react-app
生成的目錄格式以下所示:node
my-app/ README.md index.html favicon.ico node_modules/ package.json src/ App.css App.js index.css index.js logo.svg
若是你是使用npm start
來啓動配置,那麼自動會進入開發模式,此時熱替換是處於自動激活狀態,你也能夠實時地在界面或者命令行中看到錯誤提示:react
若是你使用npm run build
來編譯獲得生產環境,此時代碼會被編譯到build
目錄下,此時會自動將整個應用打包發佈,它會自動使用Webpack控件進行優化與壓縮。webpack
上述所講的create-react-app
是來自於Facebook官方,不過筆者在本身的真實應用開發中仍是習慣使用Webpack-React-Redux-Boilerplate,其容許在一個項目中配置多個應用入口,同時支持開發模式、構建模式與庫構建模式。同時筆者習慣不將webpack配置文件分紅單獨的dev與prod文件,而是合併到一個文件中。若是須要使用該模板,直接使用以下命令:git
git clone -b boilerplate https://github.com/wxyyxc1992/Webpack-React-Redux-Boilerplate/ # 克隆模板文件夾 ./install.sh # 安裝運行所須要的依賴項
獲得的模本文件夾主要由如下構成:github
├── README.md ├── README.zh.md ├── dev-config : 配置文件入口 │ ├── apps.config.js : 應用配置文件 │ ├── dev.html : 開發模式下使用的HTML文件 │ ├── devServer.js : 開發服務器 │ ├── eslint.js : ESLint配置文件 │ ├── template.html : 構建模式下推薦的HTML模板文件 │ └── webpack.config.js : webpack配置文件 ├── install.sh ├── package.json └── src : 源代碼目錄 ├── count : 某個應用 │ ├── App.js │ ├── async_library.js │ ├── colors.js │ ├── count.html │ └── count.js ├── helloworld │ ├── App.css │ ├── App.js │ ├── helloworld.css │ ├── helloworld.html │ ├── helloworld.js │ └── logo.svg ├── library │ ├── foo.js │ ├── library.html │ └── library_portal.js └── vendors.js
其核心的關於應用的配置文件即apps.config.js
,在模板項目中其配置爲:web
/** * Created by apple on 16/6/8. */ module.exports = { apps: [ //HelloWorld { id: "helloworld", title: "HelloWorld", entry: { name: "helloworld", src: "./src/helloworld/helloworld.js" }, indexPage: "./src/helloworld/helloworld.html", compiled: true }, //Count { id: "count", title: "Count", entry: { name: "count", src: "./src/count/count.js" }, indexPage: "./src/count/count.html", compiled: true } ], //開發服務器配置 devServer: { appEntrySrc: "./src/helloworld/helloworld.js", //當前待調試的APP的編號 port: 3000 //監聽的Server端口 }, //若是是生成的依賴庫的配置項 library: { name: "library_portal",//依賴項入口名 entry: "./src/library/library_portal.js",//依賴庫的入口, library: "libraryName",//生成的掛載在全局依賴項下面的名稱 libraryTarget: "var"//掛載的全局變量名 } };
開發模式下主要讀取apps.config.js
中的devServer
配置,主要是能夠配置調試的入口JS文件與開發服務器監聽的端口號。開發模式下會自動使用dev.html
做爲默認的HTML文件傳輸到瀏覽器中展現,譬如在模板項目中是將helloworld項目做爲當前正在開發的項目,切換到項目目錄下使用npm start
,便可開啓開發模式,此時在瀏覽器內打開http://localhost:3000
,便可以看到以下畫面:npm
開發模式默認是支持熱加載機制,另外,由於筆者常常須要進行移動端開發,所以須要在局域網內使用手機端進行訪問,目前開發模式已經支持以LAN地址進行訪問,你能夠直接在其餘端輸入http://192.168.1.1:3000
便可。
對於應用中存在的多應用入口,主要是在apps.config.js
中的apps下進行配置的,一個典型的應用配置爲:
id: "helloworld", //編號 title: "HelloWorld", //生成的HTML文件中的標題 entry: { name: "helloworld", //用於webpack的入口名 src: "./src/helloworld/helloworld.js" //入口文件地址 }, indexPage: "./src/helloworld/helloworld.html", //HTML模板文件地址 compiled: true //是否進行編譯
咱們使用npm run build
便可以自動進行打包,一樣的,會自動進行代碼壓縮與優化,同時還會將CSS提取到一個單獨的文件中,以在文件頭部引入。對於圖片等資源也會自動放置到dist目錄下。若是你使用npm run deploy
,則會自動地創建一個監聽dist目錄的HTTP Server,譬如在模板項目中使用npm run deploy
,而後再訪問http://localhost:8080
,既能夠獲得以下界面:
另外,構建模式下也默認設置了vendors
這個公共的Chunk來進行公共代碼提取,建議是將React等公共代碼的引入放置到src/vendors.js
文件中,這樣多應用之間共享的公共代碼就會被提取出來。
有時候,咱們但願使用Webpack編譯好的函數可以直接在Global做用域下使用,或者可以經過AMD/CMD規範引入,最直觀的用法就是可以直接掛載在script標籤下使用。關於此部分的理論說明參考Webpack Configuration。在模板項目中,關於庫構建的配置在:
//若是是生成的依賴庫的配置項 library: { name: "library_portal",//依賴項入口名 entry: "./src/library/library_portal.js",//依賴庫的入口, library: "libraryName",//生成的掛載在全局依賴項下面的名稱 libraryTarget: "var"//掛載的全局變量名 }
咱們首先構建一個基於ES6類的服務:
/** * Created by apple on 16/7/23. */ /** * @function 基於ES6的服務類 */ export class FooService { static echo(){ const fooService = new FooService(); return fooService.getMessage(); } /** * @function 默認構造函數 */ constructor() { this.message = "This is Message From FooService!"; } getMessage() { return this.message; } }
而後設置一個模板的入口文件:
/** * Created by apple on 16/7/23. */ import {FooService} from "./foo"; /** * @function 配置須要暴露的API * @type {{foo: {echo: FooService.echo}}} */ module.exports = { foo: { echo: FooService.echo } };
注意,暴露出來的接口貌似只能是靜態函數。最後咱們使用npm run build:library
進行庫構建,構建完成後再HTML文件中能夠如此使用:
alert(window.libraryName.foo.echo());