徒手撸一个简单的React开发环境

345 阅读5分钟

前言


如今,前端工程化越来越成熟,也涌现出越来越多的高效工具让开发变得简单,我们可以更加专注于业务层面,我们可以通过脚手架轻松搭建一个功能完善的React开发环境,但是在这样的“方便”下,我们越来越忽视了Webpack和babel的重要性,本文只是记录通过Webpack和Babel搭建一个简单的React环境,并不涉及理论知识与运行机制。

demo的github地址:github.com/wongyujing/…

工具

  • webpack 4.x
  • babel 7.x
  • react 16.x
  • node 10.x
  • npm 6.x

开始

一、初始化npm环境

mkdir react-app & cd react-app
npm init

初始化npm环境时会提示输入项目信息,按需输入即可,初始化成功之后项目目录下会生成一个package.jsonnode_modules/文件夹,package.json为npm的配置文件,里面包含了项目信息,依赖项和其他重要信息,node_modules/下存放项目的依赖文件。

二、webpack安装与配置

首先需要安装webpack,现在已经更新到4.x,4.x的特性为约定大于配置,省去了很多冗余的配置项,我们简单配置几行代码就可以完成项目的打包。

npm install webpack --save-dev
// 或简写
npm i webpack -D

安装完毕之后我们的项目下已经可以使用webpack命令进行打包了,不过首先需要对webpack进行简单配置。

在项目目录下新建webpack.config.js

// webpack.config.js
module.exports = {
    // mode有两个值,development和production,mode决定了webpack的构建方式
    mode: 'development'
}

此处对象的导出不可以使用es6的exports或export default,因为webpack基于node进行构建,node原生应用的是CommonJS的模块规范

我们在没有定义entry的情况下,webpack会默认读取/src/index.js,所以我们需要在项目中新建src目录,并在src下新建index.js文件,这个index.js就是我们项目的入口文件了。

// index.js
// 先随便写点什么
console.log("HelloWorld")

这个时候先进行一次简单的打包,在控制台运行webpack命令

webpack ./webpack.config.js

等待命令执行完毕,发现项目出现了一个dist/文件夹,下面有一个main.js,这个就是我们打包产生的文件,在webpack.config.js中如果没有配置output,则默认会在项目的根目录下生成dist/目录,打包产物名为main.js

为了方便,可以在package.json中配置命令

// package.json
 "scripts": {
    "build": "webpack ./webpack.config.js"
  },

这样就可以通过npm run build快速调用webpack ./webpack.config.js

三、webpack开发环境配置

如果我们在开发过程中,每改一次代码都需要重新打包的话,会大大的影响我们的效率,所以webpack提供了一个本地开发服务工具——webpack-dev-server,可以本地搭建一个web服务器,将打包生成的产物加载到内存中,读写速度更快,并且支持热更新等提升效率的功能。

首先安装webpack-dev-server

npm install webpack-dev-server --save-dev

package.json中添加命令

  "scripts": {
    "dev": "webpack-dev-server --open --compress --hot --host 127.0.0.1 --port 8080"
  },

webpack-dev-server更详细的配置可以在webpack.config.jsdevServer中进行配置。

在控制台中运行

npm run dev

通过浏览器打开http://127.0.0.1:8080/main.js,就可以看到打包的生成物main.js

这个时候打开的main.js并不是前面dist/下的main.js,其实webpack为了更好的开发效率,将打包生成物main.js存放在了计算机内存中,加载速度比放在磁盘中更快。

内存中有了main.js后,就需要一个内存中的html对他进行加载,这个时候需要html-webpack-plugin

首先项目中新建index.html

安装html-webpack-plugin

npm install html-webpack-plugin --save-dev

webpack.config.js中进行简单配置

const path = require("path");
const HtmlWebpackPlugin = require('html-webpack-plugin'); // 引入html-webpack-plugin

module.exports = {
  mode: 'development',
  // webpack插件配置
  plugins: [
    new HtmlWebpackPlugin({
      template: path.resolve(__dirname, './index.html') // 用path模块将相对路径转换成绝对路径
    })
  ]
}

2020-02-24更新,查阅资料为什么node中一定要使用path模块进行处理路径(为什么不使用相对路径),因为node在运行js过程中,代码中的相对路径并不可靠,相对路径会根据当前的process路径进行解析,所以需要转换为绝对路径

重新运行npm run dev,在浏览器打开http://127.0.0.1:8080,可以看到页面被渲染,并自动将main.js挂载在了页面中。

四、React环境配置

1. 安装reactreact-dom

npm install react react-dom --save

react为React的核心库,用于构建Virtual Dom以及实现MVVM模型
react-dom主要负责将Virtual Dom转换成dom对象

2. 在/src/index.js撰写React代码

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

// create by React element
const div = React.createElement(
  'button',
  {
    onClick: () => alert('Hello World')
  },
  'hello'
)

ReactDom.render(div, document.getElementById("app"));

index.html中添加idappdiv

<body>
    <div id="app"></div>
</body>

重新运行npm run dev

页面已经成功渲染出React元素

3. 使用JSX

使用React.createElement()可以通过JS对象的形式构建出Virsual Dom,但是却大大的降低了代码的可读性,通过JSX可以这样写React元素

const div = <div>Hello World</div>

JSX可以将编写的html格式转译成React.createElement()创建,可以在Babel官网进行验证

webpack中配置Babel即可达到效果,Babel官网提供了React环境的配置教程

安装babel-loader @babel/preset-react @babel/core

npm install babel-loader @babel/core @babel-react --save-dev

webpack.config.js中进行模块配置

const path = require("path");
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  mode: 'development',
  module: {
    rules: [
      {
        test: /.js|.jsx$/, // 正则匹配.js和.jsx文件用babel-loader进行处理
        use: 'babel-loader',
        exclude: /node_modules/ // 不处理node_modules/文件夹下的文件
      }
    ]
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: path.resolve(__dirname, './index.html')
    })
  ]
}

再添加babel配置文件

在项目根目录下添加.babelrc.json或是babel.config.json

{
  "presets": [
    [
      "@babel/preset-react"
    ]
  ]
}

关于babel的学习,有一篇文章很好的文章,点击跳转

修改react代码

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

// create by jsx
const div = <button onClick={() => console.log(1111)}>Hello</button>

ReactDom.render(div, document.getElementById("app"));

重新运行npm run dev

成功集成JSX!!!

小结

webpack在前端工程化中起到非常重要的作用,前端“现代化”项目基本已经离不开webpack了,所以我希望自己可以进一步的去探索webpack的奥秘,了解它究竟是如何实现这一切高能的操作,化“神奇”为“知识”,也希望自己不要以学习轮子为唯一目标,这样路只会越走越窄。PS:结尾真的好难写。。。😫