React 官方有一套腳手架工具,是初學者的最好選擇,可讓初學者集中注意力在 React 自己。javascript
本人對腳手架有點兒抵觸(可能主要是對未知的恐懼),從開始學習 React 就走了本身搭建開發環境的路線,這裏總結下搭建過程,但願能幫助和我同樣不肯使用腳手架工具,但又急需一個練習環境的初學者。html
文章同步發佈在我的博客站點java
基於 webpack 構建一個最小 React 項目開發環境,以把下面的 React 組件成功渲染在頁面上爲目標,即顯示 Hello React
到頁面。node
import React from 'react';
import ReactDOM from 'react-dom';
export default class HelloReact extends React.Component{
constructor(props) {
super(props);
}
render(){
return( <div>Hello React</div>);
}
}
ReactDOM.render(<HelloReact />, document.getElementById('root'));
複製代碼
mkdir react-demo
cd react-demo
複製代碼
npm init //這裏基本一路回車便可;須要你的系統安裝有 node。我安裝的 node: v8.2.一、npm: 5.3.0。
複製代碼
完成後會在項目根目錄下生成 package.json
文件:react
{
"name": "react-demo",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "wewin",
"license": "ISC"
}
複製代碼
package.json 文件的做用是記錄各個軟件的依賴關係,相似 Rails 中的 Gemfilewebpack
React 項目依賴的軟件包 react、react-dom 是必須的。由於目標是要構建使用 webpack 打包的開發環境,webpack、webpack-cli 不能少。git
npm i react -D
npm i react-dom -D
npm i webpack -D
npm i webpack-cli -D
複製代碼
此時項目結構以下:es6
react-demo tree -L 1 .
.
├── node_modules // npm 包的安裝目錄
├── package-lock.json
└── package.json
1 directory, 2 files
複製代碼
node_modules 是依賴包的安裝目錄,package-lock.json 是依賴包版本鎖定。能夠保證多個環境或者多個協做者開發環境中依賴包版本一致性。github
此時 package.json 內容以下web
{
"name": "react-demo",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "wewin",
"license": "ISC",
"devDependencies": {
"react": "^16.4.1",
"react-dom": "^16.4.1",
"webpack": "^4.12.2",
"webpack-cli": "^3.0.8"
}
}
複製代碼
首先建立 src、build 兩個目錄
➜ react-demo tree . -L 1
.
├── build // React 打包的出口, webpack 下默認打包在 dist 目錄下,我的習慣放在 build 下
├── node_modules
├── package-lock.json
├── package.json
└── src // 源碼文件,後面開發基本在這個目錄下完成
複製代碼
在 src 目錄下建立 webpack 打包的入口文件
cd src
touch index.js
複製代碼
使用 webpack 打包須要建立一個 webpack 配置文件, webpack4 不少配置項都有了默認值,這裏是我本身的一個簡單配置。
一、最基本的打包入口、出口的配置 (webpack4 入口、出口有默認配置)
const path = require('path');
module.exports = {
entry: './src/index.js',
output: {
path: path.resolve(__dirname, 'build'), // 打包出口,即打包後的文件會放在這個目錄下
filename: '[name].[hash:8].js' // 打包後的文件名
publicPath: './', // 靜態資源相對路徑
}
};
複製代碼
二、使用 html-webpack-plugin
插件自動生成文件 html 文件,並插入 <script>
標籤的特性。 [html-webpack-plugin] (https://github.com/jantimon/html-webpack-plugin#options) 插件很智能,能夠根據你的配置生成你想要的 html。
安裝和配置這個插件:
npm i html-webpack-plugin -D
複製代碼
webpack.config.js:
const path = require('path');
var HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: './src/index.js',
output: {
path: path.resolve(__dirname, 'build'),
filename: '[name][hash:8].js',
publicPath: './',
},
plugins: [new HtmlWebpackPlugin({
filename: 'index.html', // 指定生成的文件名,默認就是 index.html
template: 'src/index.html' // 指定 html 生成使用用的模版文件,我指定 使用 ```src/index.html``` 做爲模版文件
})]
};
複製代碼
模版文件 src/index.html
, 內容以下:
<!DOCTYPE html>
<html lang="en">
<head>
<title>Hello React</title>
</head>
<body>
<div id="root"></div>
</body>
</html>
複製代碼
就是開頭提到的在頁面上顯示 'Hello React' 的小應用。
src/index.js:
import React from 'react';
import ReactDOM from 'react-dom';
export default class HelloReact extends React.Component{
constructor(props) {
super(props);
}
render(){
return( <div>Hello React</div>);
}
}
ReactDOM.render(<HelloReact />, document.getElementById('root'));
複製代碼
./node_modules/.bin/webpack
複製代碼
報錯以下:
WARNING in configuration
The 'mode' option has not been set, webpack will fallback to 'production' for this value. Set 'mode' option to 'development' or 'production' to enable defaults for each environment.
複製代碼
這是須要加 'mode' 參數,加參數後運行:
./node_modules/.bin/webpack --mode=development
複製代碼
報錯:
ERROR in ./src/index.js 1:18
Module parse failed: Unexpected token (1:18)
You may need an appropriate loader to handle this file type.
> import React from react;
| import ReactDOM from react-dom;
複製代碼
這是由於 react 使用的 es6 語法須要使用: babel-loader 來翻譯 es6 及最新的 js 語法
安裝 babel loader
npm i "babel-loader@^8.0.0-beta" @babel/core @babel/preset-env -D
複製代碼
webpack.config.js 配置:
const path = require('path');
var HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: './src/index.js',
output: {
path: path.resolve(__dirname, 'build'),
filename: '[name].[hash:8].js',
publicPath: './',
},
module: {
rules: [
{
test: /\.js$/,
exclude: /(node_modules)/,
use: {
loader: 'babel-loader'
},
},
],
},
plugins: [new HtmlWebpackPlugin()]
};
複製代碼
在項目根目錄下建立 babel 的配置文件 .babelrc
:
{
"presets": [
["@babel/preset-env", {
"targets": {
"node": "current"
}
}]
]
}
複製代碼
./node_modules/.bin/webpack --mode=development
複製代碼
繼續報錯:
ERROR in ./src/index.js
Module build failed (from ./node_modules/babel-loader/lib/index.js):
SyntaxError: /Users/wewin/reactLearn/react-demo/src/index.js: Unexpected token (10:12)
8 |
9 | render(){
> 10 | return( <div>Hello React</div>);
| ^
11 | }
12 | }
13 |
複製代碼
這是由於 babel 須要配置 react preset 來支持 react 語法解析。
安裝 @babel/preset-react :
npm i @babel/preset-react -D
複製代碼
修改 babel 配置文件 .babelrc:
{
"presets": [
["@babel/preset-env", {
"targets": {
"node": "current"
}
}],
"@babel/preset-react"
]
}
複製代碼
再次編譯
./node_modules/.bin/webpack --mode=development
複製代碼
congratulations! 成功編譯:
Hash: e09b122cfb00f2a585f8
Version: webpack 4.12.2
Time: 898ms
Built at: 2018-06-29 08:19:29
Asset Size Chunks Chunk Names
main.e09b122c.js 713 KiB main [emitted] main
index.html 200 bytes [emitted]
[./src/index.js] 648 bytes {main} [built]
+ 21 hidden modules
Child html-webpack-plugin for "index.html":
1 asset
[./node_modules/html-webpack-plugin/lib/loader.js!./src/index.html] 337 bytes {0} [built]
[./node_modules/webpack/buildin/global.js] (webpack)/buildin/global.js 489 bytes {0} [built]
[./node_modules/webpack/buildin/module.js] (webpack)/buildin/module.js 497 bytes {0} [built]
複製代碼
編譯成功後在 build 目錄下生成了 index.html
和打包後的 js 文件 main.e09b122c.js
,index 文件就是 html-webpack-plugin 插件生成的,會自動插入生成的 js 文件。
build/index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<title>Hello React</title>
</head>
<body>
<div id="root"></div>
<script type="text/javascript" src="./main.e09b122c.js"></script>
</body>
</html>
複製代碼
用瀏覽器打開 build/index.html
文件,就能夠看到 Hello React
正常輸出。
本篇主要目的是總結如何搭建一個最小 React 項目的開發環境,適合抵觸腳手架工具,可是又須要一個 React 練習環境的初學者。對 webpack 及相關插件的相關東西基本一筆就帶過了。這個做爲開發還不夠智能,如不能熱加載,每次對代碼有修改就要從新編譯,從新刷新頁面,簡直毫無開發體驗可言,這些,請參考第二篇: webpack 快速構建 React 學習環境(2)-- 熱更新