从零开始,搭建基于webpack的react开发环境

从零开始,搭建基于webpack的react开发环境_第1张图片
利用react可以有效进行组件的开发与管理。其中webpack作为构建react组件的有效工具,可以大大提高我们的开发效率与使用效果。因此,网上也有了很多介绍文章。
但是,由于react与webpack版本的迭代导致在学习这些入门介绍教程时,或因存在版本问题,或因存在api变动,或因内容含糊而导致遇到很多坑。
因此,记录了一下前段时间一次搭建过程,介绍如何基于webpack搭建一个最简单的react开发环境。


准备

配置sublime

选择一个合适开发工具非常重要。前端开发可以使用的工具非常多,本文使用的是sublime。使用其他工具可以跳过这一部分
用sublime开发最好先安装一些插件,以便于支持es6语法与jsx语法,同时也能在jsx里提供emmet的功能。
插件推荐与安装可以查看这里。

安装node.js

node是基于高性能的 chrome V8 JavaScript引擎,将JavaScript的触角拓展到了服务器端。由于webpack的使用需要node环境,所以正式使用webpackreact进行开发之前,首先需要安装node.js。

这里写图片描述

Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境。Node.js 使用了一个事件驱动、非阻塞式 I/O 的模型,使其轻量又高效。Node.js 的包管理器 npm,是全球最大的开源库生态系统。

node支持window、mac、linux等平台。我们可以进入node官网,下载与安装所需要的node版本(本文使用的版本v6.5.0)。
从零开始,搭建基于webpack的react开发环境_第2张图片
安装完毕后,输入node -v可以测试安装是否成功。

项目初始化

创建项目。项目的目录结构如下:

  • app
    • components
      • title.jsx
      • clock.jsx
    • entry.js
  • build
    • index.html
    • bundle.js(自动生成)

在当前项目根目录下运行命令行,初始化项目,自动生成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打包,包括监听变化自动刷新。

简单的打包

首先,我们先做一个最简单的打包实例,来理解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,修改代码,可以看到浏览器会自动刷新显示最新的编译结果。


react+es6

通过上一部分的介绍,应该已经了解了webpack的基本用法与逻辑。该部分使用es6结合webpack来构建一个react时钟组件。关于这一部分,网上也有许多教程与实例,本文在行文中也会指出由于一些版本问题在较早期的文章中所存在的坑

使用jsx-loader

使用jsx-loader对jsx文件进行处理

npm install jsx-loader --save-dev

在webpack.config.js的module部分中添加新的loader处理器

module: {
    loaders: [{
        test: /\.jsx$/,
        loader: 'jsx-loader?harmony'
    }]
}

使用babel

安装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与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(,document.getElementById('app'));使用修改为ReactDOM.render(,document.getElementById('app'));


参考资料

  • webpack
  • react
  • nodeJs
  • React Webpack 小书
  • React+Webpack快速上手指南
  • React+ES6+Webpack深入浅出
  • stackoverflow:_reactDom2.default.render is not a function
  • stackoverflow:ERROR in Cannot find module ‘babel-core’. using react.js, webpack, and express server
  • React.render和reactDom.render的区别
  • segmentfault:使用webpack babel-loader编译es2015时候报错?

你可能感兴趣的:(react,webpack)