利用react可以有效进行组件的开发与管理。其中webpack作为构建react组件的有效工具,可以大大提高我们的开发效率与使用效果。因此,网上也有了很多介绍文章。
但是,由于react与webpack版本的迭代导致在学习这些入门介绍教程时,或因存在版本问题,或因存在api变动,或因内容含糊而导致遇到很多坑。
因此,记录了一下前段时间一次搭建过程,介绍如何基于webpack搭建一个最简单的react开发环境。
选择一个合适开发工具非常重要。前端开发可以使用的工具非常多,本文使用的是sublime。使用其他工具可以跳过这一部分。
用sublime开发最好先安装一些插件,以便于支持es6语法与jsx语法,同时也能在jsx里提供emmet的功能。
插件推荐与安装可以查看这里。
node是基于高性能的 chrome V8 JavaScript引擎,将JavaScript的触角拓展到了服务器端。由于webpack的使用需要node环境,所以正式使用webpack与react进行开发之前,首先需要安装node.js。
Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境。Node.js 使用了一个事件驱动、非阻塞式 I/O 的模型,使其轻量又高效。Node.js 的包管理器 npm,是全球最大的开源库生态系统。
node支持window、mac、linux等平台。我们可以进入node官网,下载与安装所需要的node版本(本文使用的版本v6.5.0)。
安装完毕后,输入node -v
可以测试安装是否成功。
创建项目。项目的目录结构如下:
在当前项目根目录下运行命令行,初始化项目,自动生成package.json文件
npm init
文件如下
{
"name": "alien-test",
"version": "1.0.0",
"description": "test for react",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [
"react",
"test"
],
"author": "alienzhou",
"license": "ISC"
}
这一部分,会介绍如何使用webpack打包,包括监听变化自动刷新。
首先,我们先做一个最简单的打包实例,来理解webpack的工作方式。
npm install webpack --save-dev
安装成功后在项目的node_modules(包模块)文件夹中可以看到刚下载的包。并且在pakage.json中添加了开发环境下的依赖:
"devDependencies": {
"webpack": "^1.13.2"
}
在项目根目录创建一个webpack.config.js,该文件是webpack的配置文件,会指导webpack的打包动作。文件如下
var path = require('path');
var config = {
entry: path.resolve('d:/project/react/test', 'app/entry.js'),
output: {
path: path.resolve('d:/project/react/test', 'build'),
filename: 'bundle.js',
}
}
module.exports = config;
可以看到,文件中entry指定了一个文件入口,webpack会读取该文件,输出到output所指定的路径内,生成bundle.js。而我们的index.html中需要引用打包文件bundle.js
<html>
<head>
<meta charset="UTF-8">
<title>Documenttitle>
head>
<body>
<div id="app">div>
<script src="bundle.js">script>
body>
html>
我们现在已经有了html文件,还需要一个入口文件entry.js
var title = require('components/test.js');
document.body.appendChild(title());
以及一个组件文件test.js
module.exports = function() {
var title = document.creatElement('h1');
title.text('HI, I\'m AlienZHOU');
return title;
}
需要为package.json的scripts部分添加一个新的指令build
,用以打包构建应用。
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "webpack"
}
这样就可以使用指令代替node_modules/.bin/webpack
命令
npm run build
运行完毕,可以发现在build文件夹下生成了bundle.js文件。直接在浏览器运行index.html就可以看到效果。
监听文件变化,自动刷新浏览器是非常有用的功能,使用webpack也可以非常方便实现。
webpack-dev-server是一个轻量级的node express服务器,详细介绍可以看官网相关介绍。
The webpack-dev-server is a little Node.js Express server, which uses the webpack-dev-middleware to serve a webpack bundle.
首先,安装webpack-dev-server。
npm install webpack-dev-server --save-dev
在package.json中修改scripts,添加dev
指令内容,结果如下
{
"scripts": {
"build": "webpack",
"dev": "webpack-dev-server --devtool eval --progress --colors --hot --content-base build"
}
}
这样,启动应用后,每次修改完文件内容,就会自动打包生成新的bundle.js文件。然而,现在还是不能实现浏览器的自动刷新,所以还需要最后一个配置修改:在入口处添加一个入口点,实现浏览器自动刷新。
entry: [
'webpack/hot/dev-server',
'webpack-dev-server/client?http://localhost:8080',
path.resolve('d:/project/react/test', 'app/entry.js')
]
现在,运行指令npm run dev
,在浏览器中输入localhost:8080
,修改代码,可以看到浏览器会自动刷新显示最新的编译结果。
通过上一部分的介绍,应该已经了解了webpack的基本用法与逻辑。该部分使用es6结合webpack来构建一个react时钟组件。关于这一部分,网上也有许多教程与实例,本文在行文中也会指出由于一些版本问题在较早期的文章中所存在的坑。
使用jsx-loader对jsx文件进行处理
npm install jsx-loader --save-dev
在webpack.config.js的module部分中添加新的loader处理器
module: {
loaders: [{
test: /\.jsx$/,
loader: 'jsx-loader?harmony'
}]
}
安装babel
npm install babel --save-dev
为babel添加配置文件。在项目根目录下新建文件.babelrc,添加转码规则,文件内容如下
{
"presets": ['es2015','react'],
"plugins": []
}
安装es2015转码器
npm install babel-preset-es2015 --save-dev
安装react转码器
npm install babel-preset-react --save-dev
需要stage-0语法
npm install babel-preset-stage-0 --save-dev
原因:使用es6来编写react组件与es5中的语法有多处不同,其中非常重要的一部分就是,使用静态变量来作为组件的默认属性(defaultProps)。此处使用stage-0阶段语法,是为了使用类中的静态变量语法,这种行为(the direct export of an ES6 class with a static property)如果只是用es2015转码器则会导致报错,在stackoverflow上有专门针对其的问题讨论:
“ On GitHub I got told this is a stage-1 feature, namely transform-class-properties. So I would like to implement stage-0 right away”
ERROR in ./app/components/form/index.jsx
Module build failed: SyntaxError: /Library/WebServer/Documents/yarsk.test/app/components/form/index.jsx: Unexpected token (19:19)
17 | // ES6 React Component:
18 | export default class SurveyForm extends Component {
> 19 | static propTypes = {
| ^
安装babel-loader
npm install babel-loader --save-dev
在webpack.config.js文件中添加新的loader(注意,需要放在jsx-loader后面)
module: {
loaders: [{
test: /\.jsx$/,
loader: 'jsx-loader?harmony'
}, {
test: /\.js|jsx$/,
loaders: ['babel?presets[]=es2015,presets[]=react']
}, ]
}
需要注意的地方——部分文章配置如上,但由于babel最近的调整,将一些API从babel库移至了babel-core库。所以,需要安装babel-core,否则会报错。
安装react与react-dom
npm install react --save-dev
npm install react-dom --save-dev
组件文件components/hello.jsx
import React from 'react';
export default class Hello extends React.Component{
render() {
return <div>hi alienzhou!
yoyoyo1
div>;
}
}
入口文件entry.js
import React from 'react';
import ReactDOM from 'react-dom';
import Hello from './components/hello.jsx';
main();
function main() {
ReactDOM.render( , document.getElementById('app'));
}
需要注意的地方——之前的文章使用React.render()方法。但是react从0.14版本之后被分成了react和react-dom两个部分。createElement、createClass、Component、PropTypes、children等实在React下。而render、unmountComponentAtNode、findDOMNode则放在了ReactDOM。
因此,之前的某些教程中的React.render(
使用修改为ReactDOM.render(