先附上原文链接 https://blog.usejournal.com/creating-a-react-app-from-scratch-f3c693b84658


React如果脱离我们所熟悉的环境,可能就不会很好的工作了。原因是React中有很多的关键字以及语法是node目前支持不了的(作者写这篇文章的时候是9.3.0版本)。要想很好的运行React,需要进行一系列相当麻烦的设置。对此呢,Facebook已经提供了一套配置选项来快速启动React应用,那么老铁为啥还要写这篇文章呢?

我是这么认为的,create-react-app虽好,但是它让你对React应用变得更加的陌生了(至少在你手动使用eject命令之前是这样的)。当然,还是有很多驱使你自己配置一个react应用的动机,最起码你可以搞懂它的底层到底是怎么运作的。可以极大的满足你的好奇心。

正如我提到的,在你搭建React应用的过程中会有相当多的障碍。第一点是因为node有很多语法处理不了(比方说import/export以及JSX)。第二点原因是你需要build你的文件或者在开发的过程中为你的应用启动服务—尤其是这后一种情况相当的重要。

所幸的是,我们可以通过Babel以及Webpack来解决这些问题。

安装(Setup)

开始了,第一步创建一个目录。然后使用 npm init 初始化你的应用并使用你喜爱的编辑器打开它。此时也是使用 git init 进行初始化操作的好时候。在根目录下创建如下目录结构

想的再远一些,我们最终生成的应用在提交的时候会排除掉很多的文件比如node_module。此时我们还可以创建一个.gitignore文件来排除最后的node_modules以及dist文件。(在git bash下使用touch gitignore即可创建)

public目录用来存放所有静态资源以及我们最重要的的index.html文件,毕竟react会用它来初始化render我们的app。 下面的代码是用react文档中经过小小修改的源码。放心大胆的粘贴到你的index.html中。(当然要先在public文件夹中创建一个index.html文件)


<!-- sourced from https://raw.githubusercontent.com/reactjs/reactjs.org/master/static/html/single-file-example.html -->
<!DOCTYPE html>
<html><head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"><title>React Starter</title>
</head><body><div id="root"></div><noscript>You need to enable JavaScript to run this app.</noscript><script src="../dist/bundle.js"></script>
</body></html>
view rawreact-app-tutorial index.html hosted with ❤ by GitHub

这里有两行需要特别留意。一个是div根容器。我们的react 应用可是要挂在里面

<div id="root"></div>

另一个是

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

这个文件里面会写我们的react代码。当然你可以随便取名字,但我这里就用bundle.js称呼它好了

到此,我们把我们的HTML页面弄好了。接下来我们要严肃认真起来了哦。接下来我们要做其他一些事情了。首先呢,我们要确保我们的代码会被编译,所以我们需要Babel

Babel

继续运行如下命令

npm install --save-dev @babel/core@7.1.0 @babel/cli@7.1.0 @babel/preset-env@7.1.0 @babel/preset-react@7.0.0

babel-core是主要的babel包,我们进行任何代码转换都离不开它。babel-cli允许你通过命令行的方式来进行文件的编译。preset-reactpreset-env都是用来进行代码的特殊转换。在这个例子中,env预设让我们能够将ES6+的代码转换成传统js代码。react预设则是处理JSX相关的转换问题。

在项目根目录下,创建一个文件叫做.babelrc 粘入如下代码 这里呢 我们要告诉babel 我们要使用env和react这两个预设。

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

babel还有很多很多插件你可以使用,如果env预设不能满足你的需要的话。这不是我们所需要担心的,当然你可以看这里查看详情

Webpack

接下来我们需要配置Webpack了,这里我们还需要安装一些包并将他们保存为本地依赖。

npm install --save-dev
webpack@4.19.1 webpack-cli@3.1.1
webpack-dev-server@3.1.8 style-loader@0.23.0 css-loader@1.0.0 babel-loader@8.0.2

webpack使用loader来处理不同类型的文件来进行打包。它还能帮我们在开发过程中启动应用服务,并且在代码进行改变的时候及时刷新页面。为了使用这些功能,我们需要安装不同的loaders以及准备dev-server

在我们的根目录下创建一个文件叫做webpack.config.js 这个文件会输出一个记录webpack配置的对象(Object),如下

const path = require("path");
const webpack = require("webpack");module.exports = {entry: "./src/index.js",mode: "development",module: {rules: [{test: /\.(js|jsx)$/,exclude: /(node_modules|bower_components)/,loader: "babel-loader",options: { presets: ["@babel/env"] }},{test: /\.css$/,use: ["style-loader", "css-loader"]}]},resolve: { extensions: ["*", ".js", ".jsx"] },output: {path: path.resolve(__dirname, "dist/"),publicPath: "/dist/",filename: "bundle.js"},devServer: {contentBase: path.join(__dirname, "public/"),port: 3000,publicPath: "http://localhost:3000/dist/",hotOnly: true},plugins: [new webpack.HotModuleReplacementPlugin()]
};

让我们快速来看一下这个配置文件

entry告诉webpack我们的应用程序从哪儿开始以及从哪里开始打包我们的文件。接下来的这行
**mode: “development”,**告诉webpack我们正在以开发模式运行,这使我们不必在运行开发服务器时添加模式标志

module对象定义你导出的javascript模块如何转换以及那些文件要根据给定的rules进行转换

我们的第一条规则是转换ES6以及JSX语法。test和exclude是用来匹配文件的条件。在这个例子中,它会匹配node_module
s和bower_components之外的所有目录。接下来我们要知道webpack上去使用babel来转换我们的js以及jsx文件(test中定义的规则),最后我们告诉webpack使用env中的预设。

接下来的规则是用来处理css的。因为我们这里并没有用到pre或者post css等高级功能,我们只需要确保加入style-loader以及css-loader到use属性中。css-loader需要依赖style-loader才能工作。

resolve属性告诉我们 哪些类型的文件要进行处理,这也允许我们在导入modules的时候不用写扩展名。

output属性告诉webpack我们打包之后的代码在哪里输出。publicPath属性定义了我们打包后的文件应该跑到哪个目录里。同时告诉webpack-dev-server从哪里去启动我们的服务

这个publicPath属性是一个特殊的属性 ,它可以帮助我们进行dev-server操作。他可以定义我们的公共url的目录,起码webpack-dev-server会很关心这一点。如果设置错了,就会报404错误。

最后我们在devServer属性中启动webpack-dev-server服务。这里并没有太多的要求。只要标出我们的静态资源放那儿(比方说我们的index.html)以及我们要在哪个端口启动该服务。你可以看到devServer也有一个publicPath,这里的publicPath是为了告诉server我们打包后的文件在哪儿

最后需要留心的是 output.publicPath 和 devServer.publicPath是不一样的。重要的事情说三遍。

最后呢 为了实现热更新,及时响应我们的changes 只需要在devServer中将hotOnly设置为true 当然我们还需要实例化我们的HMR插件(Hot Module Replacement)

大功告成了

接下来看React代码了

React

首先我们需要额外安装两个依赖包 react@16.5.2 以及 react-dom@16.5.2

我们需要告诉Reactapp 我们要把reactapp挂在到哪个文件(这里是index.html)
在src目录下创建一个index.js文件
粘入以下代码

import React from "react";
import ReactDOM from "react-dom";
import App from "./App.js";
ReactDOM.render(<App />, document.getElementById("root"));

ReactDom.render 告诉react渲染什么,在哪儿渲染。这里我们将要渲染一个叫做APP(马上就要创建了)的组件,渲染到我们index.html中的一个div中。

现在在src中创建另外一个文件 叫做App.js 粘入以下代码(如果你习惯使用create-react-app的话,这段代码你应该比较熟悉,这是一个react组件)

import React, { Component} from "react";
import "./App.css";class App extends Component{render(){return(<div className="App"><h1> Hello, World! </h1></div>);}
}export default App;

接下来我们再加点儿css src目录下创建一个App.css


.App {margin: 1rem;font-family: Arial, Helvetica, sans-serif;
}

你最终的代码结构看起来是这个样子的

最后我们可以执行webpack-dev-server --mode development 命令启动我们的服务。当然我建议你把这个放到package.json中的start命令里面

(令人愤怒的结果搞到现在跑不起来)
问题出在哪里?!!!!!

检查之后发现自己少执行了 没有安装react@16.5.2 以及 react-dom@16.5.2
以及配置babelrc 这个文件里面写了个才能在webpack里面用

Finishing HMR

如果你现在启动服务,当你做了内容更改之后,需要刷新浏览器才能看到效果,我们想让浏览器内容自动改变怎么办?

emm HMR需要知道替换什么,目前我们并没有给它任何东西。因此,我们要使用react团队提供给我们的一个包:
react-hot-loader@4.3.11
你可以按照惯例安装好它

你可以安全的将react-hot-loader作为常规依赖项安装而不是开发以来项,因为他可确保不会再生产环境执行并且占用的空间很小。

接下来 在app.js中引入 react-hot-loader 将代码更改如下

import React, { Component} from "react";
import {hot} from "react-hot-loader";
import "./App.css";class App extends Component{render(){return(<div className="App"><h1> Hello, World! </h1></div>);}
}export default hot(module)(App);

现在当你更改内容的时候,按下保存 浏览器就会自动刷新了

最后一些细节

你可能注意到一些有趣或者说惊讶的事情,当你启动项目的时候 你在dist目录中看不到编译之后的文件。 这是因为webpack-dev-server将打包后的文件在内存当中运行了,一旦服务停止,文件就消失了。所以要想生成build之后的文件。我们需要好好的利用webpack。 要在package.json文件中添加一条build指令 webpack --mode development 你可以用生产来代替开发。但是如果你忘记写–mode 它会自动执行后一种情况并且给你一个警告。

以上的内容几乎涵盖了你在开发react应用中的所有内容,而不需要去触碰craete-react-app 当然 还有很多的东西要添加。比方说,webpack无法处理图片,但是我们有处理图片所需的loader。将这个任务留给你,

我希望这篇文章能让你对react-app架构搭建带来一些启发。关于babel以及webpack我没有太深入,但是建议你不放过本文的任何一个链接。这两个工具乍一看令人生畏,但他们可以让你的开发水平提升一个质的飞跃!

如果你还搞不懂,这里有github项目。你也可以查看更老版本的实现(这个可能有点难)。或者在twitter上打招呼

这篇文章写于2018.4.24
软件包版本 2018.5.13
反馈webpack-dev-server的bug修复 2018.6.16
反馈对React以及软件包的更新 2018.9.23

手把手从底层搭建react应用(如何自己实现react脚手架)(webpack环境搭建)相关推荐

  1. React系列---Webpack环境搭建(二)不同环境不同配置

    React系列---Webpack环境搭建(一)手动搭建 React系列---Webpack环境搭建(二)不同环境不同配置 React系列---Webpack环境搭建(三)打包性能优化 实际项目中,往 ...

  2. Spring Boot+Vue从零开始搭建系统(一):项目前端_Vuejs环境搭建

    前言 博主本身是一直从事Java后端开发,一直想独立开发一套完整前端和后端技术结合的项目来提升自己的技术水平,经过对业界的一些热点技术的了解并对技术栈选型考虑后,博主打算利用Vue.js和Spring ...

  3. linux上 arm开发环境搭建,详解 LINUX下QT For ARM开发环境搭建过程

    LINUX下QT For ARM开发环境搭建过程是本文介绍的内容,不多说,先来看内容.在PC上,我们需要得到两个版本的Qt,分别是:Qt-4.5.2和QtEmbedded-4.5.2-arm.前者包括 ...

  4. 初识webpack与webpack环境搭建

    文章目录 认识webpack配置文件 webpack配置结构 环境搭建安装Node.js和NPM NVM安装 Nodejs和NPM安装 环境搭建安装webpack和webpack-cli 创建空目录和 ...

  5. 【Linux集群基础环境搭建】基于虚拟机的多节点Linux网络环境搭建(超详细)

    基于VMWare虚拟机的多节点Linux网络环境搭建 一.使用工具 二.方案设计 三.实现过程 1.安装VMWare虚拟机软件 2. 创建虚拟机节点controller并安装CentOS 3. 通过节 ...

  6. 手把手教你:【史上最全】C++开发环境搭建:win732位下VS2010+Boost_1_53_0+Qt5.2+MySql搭建

    我想说:这两个多星期走得很辛苦,没有人告诉我win732位系统下VS2010+Boost_1_53_0+Qt5.2+MySql开发环境如何搭建,自己一步一步摸索,重装了无数遍系统,试了几十种方法,才艰 ...

  7. 搭建VUE大屏展示项目(一)环境搭建

    文章目录 环境安装 搭建项目 工程整理 问题 github地址 环境安装 升级npm npm install -g npm 切换到淘宝镜像 npm config set registry " ...

  8. webpack环境搭建使用

    1.安装: 首先要安装 Node.js, Node.js 自带了软件包管理器 npm,Webpack 需要 Node.js v0.6 以上支持,建议使用最新版 Node.js. 用 npm 安装 We ...

  9. QT5.14搭建MSVC(VS2017) x86 以及64位编译器开发环境搭建(GDB配置)

    一.引言 今天想要使用QT+echarts实现炫酷的界面,但是一开始想的很简单,查找资料才发现,我之前一直使用的MinGw编译器无法使用QWebEngine,这个就很头秃,懵逼,今天搞了快一整天配置环 ...

最新文章

  1. 【开发工具】Jupyter Notebook 的快捷键
  2. binary - 从(向)二进制串插入和提取字段 / BINARY FORMAT BINARY SCAN
  3. 从qplot开始入门
  4. excel判断两列中同一行的数据是否一致
  5. 如何在Shell脚本中使用if-else?
  6. 十一这里最好玩啦!快来一起玩耍!
  7. 关于CSDN是什么网站
  8. YetAnotherKeyDisplayer(YAKD屏幕上显示键盘操作)源码下载及编译(Win10,VS2022)
  9. 嵌入式C编程中的设计模式之二——状态机模式
  10. 磁碟机病毒***猖獗教你应对方法
  11. 通赢A5管理系统服务器连不进,赢通软件A5A6系列管理系统参数设置说明
  12. 借助 Material You 动态配色丰富您的应用
  13. 云计算对网络学习,主要有哪些影响?
  14. CS5211/eDP转LVDS转换器方案设计电路图
  15. python open permission denied_spark-submit python 程序,/home/.python-eggs permission denied 问题解决...
  16. UE4--用插件加载第三方库lib/dll(lsl)
  17. 数字电视业务PSI/SI学习系列
  18. 车机蓝牙通话流程分析的流程分析
  19. 学了这么久python,不会连自己啥python版本都不知道吧?
  20. 和2016年的自己握手言和

热门文章

  1. 热爱工作,拥抱明天——读《干法》有感2800字
  2. Xilinx-7Series-FPGA高速收发器使用学习—TX发送端介绍
  3. python实现链表(一)
  4. ROS入门、ROS完整教程
  5. 服务过美国总统竞选的非传统投票UI【demo已放出】
  6. 简单的小故事解释网络常用术语
  7. 关于uboot的简介——uboot对Flash与DDR的管理
  8. Xshell登录进入CentOS 6.5系统后,Python交互模式和数据库模式下,出现乱码的问题及解决方法
  9. 1个月写900多条用例,二线城市年薪33W+的测试经理能有多卷?
  10. 2021.12.9 java代码对接sap接口(soap协议、webservice)