phenomLi / Blog

Comments, Thoughts, Conclusions, Ideas, and the progress.
219 stars 17 forks source link

React开发环境搭建教程 #6

Open phenomLi opened 6 years ago

phenomLi commented 6 years ago

在前端工程化大潮流下,正儿八经开始一个项目是要耗不少时间的,特别像React和angluar这种大型框架环境的搭建。今天我要介绍的是如何快速搭建一个React开发环境。

传统React开发模式

script把所有需要的库引入,这是最最传统的开发方式。

<script src="./react.js"></script>
<script src="./react-dom.js"></script>
<script src="./JSXtransformer.js"></script>    

这种方式最明显的优点就是快,简单。但是缺点同时也很明显,就是当需要引用的库一旦多起来的话,库与库之间的依赖关系就很难处理了,比如一个依赖于Jquery的库,一定要保证Jquery比这个库先引入。还有一个就是有多少个库就要有多少次http请求,把10份文件合并成1份加载要比一份文件拆成10份加载要节省资源。
而且因为React推荐使用JSX(虽然不是强制,但是当要渲染的元素结构很深的时候使用函数式会把你逼疯),浏览器不能直接识别JSX,所以要经过JSXtransformer.js转译,所以很明显,在页面内转译也会耗费性能,而且看起来这份有苦又累的工作根本不需要浏览器来完成,正常来讲把JSX转译这个步骤最好是在引入前就完成。


使用babel

什么是bebel? babel是一个基于node的,能把浏览器不能识别的语句(比如JSX,Typescript,es6等)转译成可以识别的(es5)语句的一个开发工具,详细请问百度。 首先我们先安装babel:

$ cnpm install babel babel-cli babel-core --save

然后再根据需要安装转译器:

$ cnpm install babel-preset-es2015 babel-preset-react --save

因为React官方推荐使用ES6语法编写React项目,我这里安装了两个转译器,一个是babel-preset-es2015,用作转译ES6语法,另一个是babel-preset-react,用作转译JSX语法。
全都安装完毕后,我们需要在项目根目录下新建一个名为.babelrc(没错就是这个鬼名字,前面有一个点)的babel配置文件,里面将会描述babel该如何工作。

{
  "presets": ["es2015", "react"],
  "plugins": []
}

preset里面填上需要用到的转译器,我这里把刚刚安装好的ES6转译器和JSX转译器写上。
到目前为止,十分简单地就把babel给配置好了,现在尝试一下把一段ES6语法的js转译。 新建一个文件,名为a.js,在里面写下如下内容:

/*
*a.js
*/

const a = () => {
    console.log('2');
};

然后打开command,进入项目目录,输入:

$ babel a.js -o b.js

可以看到项目目录下多了一个b.js文件,打开它可以看到转译后的内容:

/*b.js*/

'use strict';

var a = function a() {
    console.log('2');
};


有时候会觉得每次改动文件后都要手动执行编译太麻烦了,可以在一开始指定babel进行文件监视自动编译:

$ babel a.js -w -o b.js

输入命令后,每当a.js有改动后babel都会自动更新b.js
好了到目前为止,编译JSX和ES6的工作已经不用浏览器去完成了,我们也不用引入那个JSXtransformer.js了,通常来说这已经够了,但是我们的追求还不止如此。

使用webpack

什么是webpack? 这个恐怕我也说不清楚,官方定义是一个打包工具,总之在我眼里webpack什么都能干,感觉已经超出打包工具的范畴了(具体还是问度娘吧)。
那我们为什么要用webpack? 其实文章开头已经提到了,在一个要引入一定数量的库的项目中,库间依赖和请求资源浪费是个不能被忽视的问题,最好的解决方法是我们把所有的库(甚至css和图片等静态资源,强大的webpack啊!)都打包在一个js文件里面,我们就用webpack来干这个。
首先我们安装webpack。

$ cnpm install webpack --save

然后我们在项目目录下新建一个文件,名为webpack.config.js,里面写入内容如下:

const webpack = require('webpack');

module.exports = {
     
};

这个是最简单的webpack配置文件结构。webpack需要一个入口文件,我们新建一个名为entry.js的入口文件,然后把需要用到的库引入:

/* entry.js */

import React from 'react';
import ReactDOM from 'react-dom';

我们这里要用到react和react-dom两个库,但是我们还没安装这两个库,所以先安装:

$ cnpm install react react-dom --save

安装完成后我们就可以对webpack.config.js进行配置了:

const webpack = require('webpack');

module.exports = {
    //入口文件
    entry: './entry.js',
    //打包后输出的文件
    output: {
        filename: "./build/bundle.js"
    }
};

配置好后,我们进入command,输入webapck,跑起来。

之后可以看到我们的项目文件夹下面多了一个build目录,里面已经生成了我们的打包文件bundle.js

因为这个bundle.js已经包含了我们全部所需要的库,因为代码都在一个文件里面了,所以没有依赖顺序的烦恼,也就是说我们在html里面,只需要引入我们的bundle.js就可以了。

<script src="./build/bundle.js"></script>


同样的,如果觉得每次更改文件都要重新打包很麻烦,也可以使用命令

$ webpack --watch

来监视文件改动,自动打包。 之后我们只要把babel的输出文件改成entry.js,就可以实现

编写源代码  ----->  转译JSX和ES6语法  ----->  打包所有库

这样子的流程了。


现在有了webpack,库的问题也解决了,但是问题是每次开发都要打开两个command来监听文件改动,岂不是很麻烦?别急,还有解决办法。


使用babel-loader

使用babel-loader可以把babel作为一个插件放进webapck里面,实现在打包的过程中转译。

首先安装babel-loader

$ cnpm install babel-loader --save

然后最重要的是在webpack.config.js中吧babel-loader给配置好:

const webpack = require('webpack');

module.exports = {
    //入口文件
    entry: './entry.js',
    //打包后输出的文件
    output: {
        filename: "./build/bundle.js"
    },
    //加载webpack插件
    module: {
        rules:[{
            //检测是否为js文件
            test: /\.js$/,
            //使用babel-loader
            use: 'babel-loader',
            //除去node_module里面的文件
            exclude: /node_modules/,
        }],
    } 
};

配置好之后,我们写一个小小的react项目看看效果,先新建一个html文件:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title></title>
</head>
<body>

<!--   react组件容器  -->
<div id="box"></div>

<script src="./build/bundle.js"></script>
</body>
</html>

然后编写我们的entry.js:

/* entry.js */

import React from 'react';
import ReactDOM from 'react-dom';

/*  一个小文字组件  */
class Text extends React.Component {
    render() {
        return <h1>Phenom</h1>;
    }
}

/*  挂载组件 */
ReactDOM.render(
    <Text />,
    document.getElementById('box')
);

最后webpack命令,走起!

$ webpack --watch


打开刚刚的html文件,可以看到组件成功渲染出来了,一切都很完美。



我们现在已经把编译和打包揉在一起了,开发的时候只要打开一个command并且输入一个webpack命令就能自动完成,个人来讲已经很满意。这个webpack的玩法其实还有很多很多,webpack是一个十分强大而且复杂的工具,光是配置文件这一项里面水已经很深(而且听说webpack3也快要出来了。。)。前面已经提到了,用webpack甚至可以把css打包进js里面,图片转成base64也打包进js里面,这样子可以做到请求最小化。所以,关于前端自动化,工程化,还有大把大把的坑要踩。