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)-- 热更新