工欲善其事必先利其器,在進(jìn)行 React 的開(kāi)發(fā)時(shí),通常會(huì)結(jié)合 Webpack 和 ES6 一起進(jìn)行。本文講的正是如何使用 React + Webpack + ES6 進(jìn)行組合開(kāi)發(fā)。關(guān)于 React 的入門,后面另開(kāi)一文。
本文最終的輸出是一個(gè) Hello World 。
本文所涉及的代碼在 這里 ,可以直接作為一個(gè)種子項(xiàng)目使用:
git clone https://github.com/huangtengfei/react-webpack-es6.gitcd react-webpack-es6npm installnpm run dev如果你使用 sublime 開(kāi)發(fā),可以安裝 sublime-react 插件。
安裝依賴項(xiàng)
在項(xiàng)目目錄下 ,初始化一個(gè)
package.json
文件,執(zhí)行:npm init
安裝
react
和react-dom
依賴:npm install react react-dom --save
安裝
webpack
和webpack-dev-server
依賴:npm install webpack webpack-dev-server --save-dev
安裝
babel
依賴:npm install babel-loader babel-core babel-PReset-react babel-preset-es2015 --save-dev
代碼編寫
本文示例最終的目錄結(jié)構(gòu)是這樣的:
--your project |--components(組件目錄) |--Hello(組件1) |--imgs |--bg.png |--index.jsx |--index.less |--World(組件2) |--index.jsx |--index.less |--index.js(入口文件) |--build(輸出目錄) |--index.html |--bundle.js(輸出文件,由 webpack 打包后生成的) |--package.json |--webpack.config.js創(chuàng)建 React 組件
按照前面的目錄結(jié)構(gòu),新建一個(gè) components 文件夾,存放所有組件。
在 components 下建一個(gè) Hello 文件夾,用來(lái)存放 Hello 組件的邏輯和樣式。
Hello/index.js
的代碼如下:import React from 'react';import ReactDOM from 'react-dom';class Hello extends React.Component { render() { return <h1>Hello</h1> }}ReactDOM.render(<Hello />, document.getElementById('hello'));World 組件的開(kāi)發(fā)同上,略去。
創(chuàng)建頁(yè)面
在 build 目錄下創(chuàng)建一個(gè) HTML 頁(yè)面,來(lái)使用前面創(chuàng)建的兩個(gè)組件。
index.html
的代碼如下:<!DOCTYPE html><html> <head> <meta charset="UTF-8"> <title>Hello World</title> </head> <body> <div id="hello"></div> <div id="world"></div> </body></html>使用 Webpack 打包
Webpack 是一個(gè)前端模塊加載兼打包工具,可以對(duì) JS、CSS 和 圖片 等都作為模塊來(lái)使用和處理。對(duì)不同類型的需要編譯的文件,需要使用相應(yīng)的加載器(比如用 babel 轉(zhuǎn)譯 ES6)。
另外,由于 Webpack 需要一個(gè)入口文件來(lái)進(jìn)行分析和處理,需要先將 React 組件引入到一個(gè)主文件。
從前文的目錄結(jié)構(gòu)可以看出,
components/index.js
就是這個(gè)主文件,它的代碼如下:import Hello from './Hello/index.jsx';import World from './World/index.jsx';下面就是 Webpack 配置文件
webpack.config.js
的編寫,代碼如下:var path = require('path');var webpack = require('webpack');var ROOT_PATH = path.resolve(__dirname);var APP_PATH = path.resolve(__dirname, './components/index.js');var BUILD_PATH = path.resolve(__dirname, './build');module.exports = { entry: APP_PATH, output: { path: BUILD_PATH, filename: 'bundle.js' }, module: { loaders: [{ test: //.jsx?$/, loaders: ['babel-loader?presets[]=es2015,presets[]=react'] }] }}最后,需要將編譯打包后的文件
bundle.js
引入到index.html
中:<body> ... <script src="./bundle.js"></script></body>構(gòu)建和啟動(dòng)
構(gòu)建
前面的開(kāi)發(fā)完成后,需要執(zhí)行
webpack.config.js
中的構(gòu)建任務(wù),生成bundle.js
,這個(gè)操作可以在package.json
中配置:"scripts": { "build": "webpack"}執(zhí)行
npm run build
完成構(gòu)建,此時(shí)打開(kāi)index.html
,即可看到效果。啟動(dòng)服務(wù)器
但這種方式顯得略 low,一是它是雙擊以文件的形式打開(kāi) HTML 頁(yè)面,二是每次有更改都要手動(dòng)執(zhí)行
npm run build
重新打包。一種更好的方式是啟動(dòng)一個(gè)靜態(tài)資源服務(wù)器,監(jiān)聽(tīng)文件內(nèi)容修改并自動(dòng)打包。在這里用的是前面安裝好的
webpack-dev-server
,在package.json
中配置:"scripts": { "dev": "webpack-dev-server --devtool eval --progress --colors --hot --content-base build"}簡(jiǎn)單解釋一下 dev 中各個(gè)參數(shù)的含義:
webpack-dev-server
在localhost:8080
建立一個(gè) Web 服務(wù)器;--devtool eval
映射編譯好的源碼,用于調(diào)試;--progress
顯示代碼打包進(jìn)度;--colors
表示在命令行中顯示顏色;--content-base
來(lái)指定 server 啟動(dòng)后的內(nèi)容目錄。執(zhí)行
npm run dev
啟動(dòng) server,此時(shí)打開(kāi)http://localhost:8080
,即可看到效果。修改一下 Hello 或者 World 組件中的內(nèi)容,刷新頁(yè)面,你會(huì)發(fā)現(xiàn)瀏覽器中內(nèi)容也相應(yīng)改變了。自動(dòng)刷新
前面實(shí)現(xiàn)了對(duì)文件修改的監(jiān)聽(tīng)和自動(dòng)打包,但瀏覽器還需要手動(dòng)刷新。其實(shí)可以在 Webpack 的配置文件中增加一個(gè)入口點(diǎn),實(shí)現(xiàn)自動(dòng)刷新。
··· entry: [ 'webpack/hot/dev-server', 'webpack-dev-server/client?http://localhost:8080', APP_PATH ],···這樣,應(yīng)用在修改后,瀏覽器就會(huì)自動(dòng)刷新了。
更完整的種子
其實(shí)講到這里本文已經(jīng)可以結(jié)束了,不過(guò)為了讓種子更完整,并體現(xiàn) Webpack 的強(qiáng)大,再加上點(diǎn)樣式和圖片吧。
處理樣式
不管什么類型的資源,Webpack 都需要相應(yīng)的 loader 來(lái)處理。對(duì)于普通的 css,需要
css-loader
和style-loader
兩種 loader,前者會(huì)遍歷所有 css 并對(duì)url()
處理,后者將樣式插入到頁(yè)面的 style 標(biāo)簽中。對(duì)于預(yù)編譯 css 語(yǔ)言,還需要額外的 loader,比如less-loader
或sass-loader
,這里用 less 舉例。首先,安裝 loader :
npm install less-loader css-loader style-loader --save-dev然后,在
webpack.config.js
中配置 loader,注意 loader 的處理順序是從右到左的:...{ test: //.less$/, loader: 'style!css!less'}...配置完之后要重新運(yùn)行一下
npm run dev
接著,在 Hello 和 World 組件中各添加一個(gè)樣式文件,這里用
Hello/index.less
舉例:@lightgrey: #ccc;h1 { background: @lightgrey;}最后,在
components/index.js
中引入 less 文件:import './Hello/index.less';import './World/index.less';切換到瀏覽器,看一下是不是有變化了呢~
處理圖片
為了減輕網(wǎng)絡(luò)請(qǐng)求的壓力,有時(shí)候會(huì)有將小圖片轉(zhuǎn)成 BASE64 字符串的需求,這個(gè)可以通過(guò)
url-loader
來(lái)實(shí)現(xiàn)。同處理樣式中的操作,首先安裝
url-loader
:npm install url-loader --save-dev然后配置
webpack.config.js
:...{ test: //.(png|jpg)$/, loader: 'url?limit=50000'}...重新重新運(yùn)行一下
npm run dev
接著,在 Hello 組件下建一個(gè)
imgs
文件夾,并放入一張小于 50K 的bg.png
做背景圖片,然后修改Hello/index.less
文件:h1 { background: url('./img/bg.png');}切換到瀏覽器,審查元素,看一下圖片是不是轉(zhuǎn)成 BASE64 字符串了呢~
到此為止,這已經(jīng)是一個(gè)較為完整的種子了。想對(duì) React 、Webpack 和 ES6 各自做深入了解的,請(qǐng)自行查閱資料~
補(bǔ)充
loader 的寫法
在使用 Webpack 打包小節(jié)
webpack.config.js
的編寫中,babel-loader
最初我是這樣寫的:loaders: [{ test: //.jsx?$/, loader: 'babel-loader', query: { presets: ['es2015', 'react'] }}]后來(lái)為了使用熱加載,引入了
react-hot
,loader 要改為 loaders,即:... loaders: ['babel-loader', 'babel-loader'], query: { presets: ['es2015', 'react'] }...這時(shí)在執(zhí)行構(gòu)建的時(shí)候,會(huì)報(bào)錯(cuò) Error: Cannot define ‘query’ and multiple loaders in loaders list ,于是改成這種寫法。不過(guò)后來(lái)直接用 webpack-dev-server 的
--hot
選項(xiàng),也沒(méi)引入react-hot
了,但此處寫法仍保留,便于后面擴(kuò)展 loader 。安裝 less-loader 報(bào)錯(cuò)
如果在安裝樣式的幾個(gè) loader 的時(shí)候,報(bào)以下錯(cuò)誤:
UNMET PEER DEPENDENCY less@^2.3.1不妨試試用 cnpm 單獨(dú)安裝 less :
tnpm i less@^2.3.1
新聞熱點(diǎn)
疑難解答
圖片精選