# 搭建一个 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>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://yyaozhibo.gitbook.io/qian-duan-xue-xi/webpack/da-jian-yi-ge-react-gong-cheng.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
