> For the complete documentation index, see [llms.txt](https://yyaozhibo.gitbook.io/qian-duan-xue-xi/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://yyaozhibo.gitbook.io/qian-duan-xue-xi/webpack/da-jian-yi-ge-react-gong-cheng.md).

# 搭建一个 React 工程

## 直接开始

### 初始化项目

1. 先创建一个目录并进入

```javascript
mkdir react-cli && cd react-cli

```

1. 初始化项目,填写项目信息（可一路回车）

```javascript
npm init
```

### 安装webpack

```
yarn global add webpack -D 
yarn global add webpack-cli -D 
```

* yarn使用add添加包，-D等于--save-dev -S等于--save
* -D和-S两者区别：-D是你开发时候依赖的东西，--S 是你发布之后还依赖的东西
* -g是全局安装，方便我们后面使用webpack命令（全局安装后依然不能使用的小伙伴，检查下自己的环境变量PATH）

安装好后新建build目录放一个webpack基础的开发配置webpack.dev.config.js

```
mkdir build && cd build && echo. > webpack.dev.config.js
```

配置内容很简单，配置入口和输出

```javascript
const path = require('path');

module.exports = {
 
    /*入口*/
    entry: path.join(__dirname, '../src/index.js'),
    
    /*输出到dist目录，输出文件名字为bundle.js*/
    output: {
        path: path.join(__dirname, '../dist'),
        filename: 'bundle.js'
    }
};
```

然后根据我们配置的入口文件的地址，创建../src/index.js文件(请注意src目录和build目录同级)

```
mkdir src && cd src && echo. > index.js
```

然后写入一行内容

```javascript
document.getElementById('app').innerHTML = "Hello React";
```

现在在根目录下执行webpack打包命令

```
webpack --config ./build/webpack.dev.config.js
```

我们可以看到生成了dist目录和bundle.js。（消除警告看后面mode配置） 接下来我们在dist目录下新建一个index.html来引用这个打包好的文件

```markup
<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
<div id="app"></div>
<script type="text/javascript" src="./bundle.js" charset="utf-8"></script>
</body>
</html>
```

然后双击打开index.html,我们就看到浏览器输出

```
Hello React
```

这样我们一个基本的打包功能就做好了！！！

### mode

刚才打包成功但是带有一个警告，意思是webpack4需要我们指定mode的类型来区分开发环境和生产环境，他会帮我们自动执行相应的功能，mode可以写到启动命令里--mode=production or development，也可以写到配置文件里,这里我们将 webpack.dev.config.js里面添加mode属性。

```
/*入口*/
    entry: path.join(__dirname, '../src/index.js'),
    mode:'development',
```

在执行打包命令，警告就消失了。

### babel

{% hint style="info" %}
Babel 把用最新标准编写的 JavaScript 代码向下编译成可以在今天随处可用的版本。 这一过程叫做“源码到源码”编译， 也被称为转换编译。(本教程使用的babel版本是7，请注意包名和配置与6的不同)
{% endhint %}

* @babel/preset-env 用于解析 ES6
* @babel/preset-react 用于解析 JSX
* babel-loader 加载器

```
yarn add @babel/core @babel/preset-env @babel/preset-react babel-loader -D
```

然后在根目录下新建一个babel配置文件

```javascript
babel.config.js

const babelConfig = {
   presets: ["@babel/preset-react", "@babel/preset-env"],
    plugins: []
}

module.exports = babelConfig;
```

修改webpack.dev.config.js，增加babel-loader！

```javascript
/*src目录下面的以.js结尾的文件，要使用babel解析*/
/*cacheDirectory是用来缓存编译结果，下次编译加速*/
module: {
    rules: [{
        test: /\.js$/,
        use: ['babel-loader?cacheDirectory=true'],
        include: path.join(__dirname, '../src')
    }]
}
```

现在我们简单测试下，是否能正确转义ES6\~

修改 src/index.js

```javascript
 /*使用es6的箭头函数*/
    var func = str => {
        document.getElementById('app').innerHTML = str;
    };
    func('我现在在使用Babel!');
```

再执行打包命令

```javascript
webpack --config ./build/webpack.dev.config.jsj
```

现在刷新dist下面的index.html就会看到浏览器输出

```
我现在在使用Babel!
```

有兴趣的可以打开打包好的bundle.js，最下面会发现ES6箭头函数被转换为普通的function函数

### react

接下来是我们的重点内容，接入react

```
yarn add react react-dom -S
```

注：这里使用 -S 来保证生产环境的依赖

修改 src/index.js使用react

```jsx
import React from 'react';
import ReactDom from 'react-dom';

ReactDom.render(
    <div>Hello React!</div>, document.getElementById('app'));
```

执行打包命令

```
webpack --config ./build/webpack.dev.config.js
```

刷新index.html 看效果。

接下来我们使用react的组件化思想做一下封装，src下新建components目录，然后新建一个Hello目录，里面创建一个index.js，写入：

```jsx
import React, { PureComponent } from 'react';

export default class Hello extends PureComponent  {
    render() {
        return (
            <div>
                Hello,组件化-React!
            </div>
        )
    }
}
```

然后让我们修改src/index.js，引用Hello组件！

```jsx
import React from 'react';
import ReactDom from 'react-dom';
import Hello from './components/Hello';

ReactDom.render(
    <Hello/>, document.getElementById('app'));
```

注：import 模块化导入会默认选择目录下的index文件，所以直接写成'./components/Hello'

在根目录执行打包命令

```
webpack --config ./build/webpack.dev.config.js
```

打开index.html看效果咯\~

### 命令优化

每次打包都输入很长的打包命令，很麻烦，我们对此优化一下。

修改package.json里面的script对象，增加build属性，写入我们的打包命令。

```
"scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "webpack --config ./build/webpack.dev.config.js"
  },
```

现在我们打包只需要执行npm run build就可以啦！（除了start是内置命令，其他新增的命令都需要用run去运行）<br>

### 参考

<https://juejin.im/post/5c9d88ea6fb9a070c6189d69#heading-7>
