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