”高级女秘书“ —— webpack 创建一个 React 应用

webpack

webpack 简介

有说 webpack 是打包机,也有人说它是加工厂,我总感觉它像一个高级的女秘书。今天的故事又开始了:

话说有位上世纪80年代下海创业成功的大老板,但是呢,文化程度不高,随着历史的车轮滚滚向前,也随着公司越做越大,公司的业务也在逐步扩大,准备开拓海外市场,他想找个翻译最好也能辅助一下自己的工作,一是托朋友四处打探,终于找到了这么一位年轻貌美,能力极强的秘书。经过老板与秘书的配合,最终成功拓展了海外市场,让公司做大做强。(故事纯属瞎....,我就不信有雷同)

女秘书的能力到底有哪些呢?

  • 翻译能力
  • 文件整理能力
  • 关联文件,工具的查找与使用的能力
  • 归纳总结的能力
  • 思维灵活

我们都知道,构建工具 webpack 现如今也是各大公司炙手可热的"大红具",虽然各种工具还在层出不穷,但 webpack 至少现在还是年富力强,所以还是学学吧。

webpack 的能力:

  • 编译能力:webpack 可以把前面提到 JSX 等浏览器不能识别的代码编译成 JavaScript,Babel 也支持 ESNext 句法,一句话就是 webpack 可以把 各种文件编译成浏览器可以识别的代码。
  • 代码整理能力:webpack 可以把代码拆分,进行按需加载,也可以把代码合并,简化代码,让文件更少,更小。
  • 依赖管理:webpack 能把各个文件间的依赖逐一进行解读,编译,整合,以及一些三方插件的引入。
  • 模块管理:构建高效,简单,可复用的组件,最后将组件合并为一个完整的应用。
  • 热更新能力:监听源码变化,立即更新有变化的模块。这一点在前端的开发,调试中省去了多少的 Ctrl + F。

webpack 构建项目

我们通过构建一个 React 项目来进一步了解 webpack。

  1. 我们先打开终端,在合适的位置上创建一个 weekplan-app 项目文件夹;
bash 复制代码
mkdir weekplan-app
cd weekplan-app
  1. 创建项目 和 package.json 文件;
csharp 复制代码
npm init -y

此刻可以看看项目文件夹里边是不是多了 package.json 文件了。

  1. 安装 react 和 reactDOM;

    npm install react react-dom serve

目前,weekplan-app 文件夹下就多了 node_modules 文件夹,package-lock.json 文件;

  1. 打开代码编辑器我们来把项目文件按如下结构补全;
  • 在 originalData 下创建 planList.json 文件:
css 复制代码
[  {    "title": "周一的计划", "index": 1, "todoItems": [      { "index": 1, "time": "7:00 PM", "matters": "运动健身" },      { "index": 2, "time": "9:00 PM", "matters": "阅读" }    ]
  },
  {
    "title": "周二的计划", "index": 2, "todoItems": [
      { "index": 1, "time": "7:00 PM", "matters": "练习萨克斯" },
      { "index": 2, "time": "8:00 PM", "matters": "看一部电影" }
    ]
  },
  {
    "title": "周三的计划", "index": 3, "todoItems": [
      { "index": 1, "time": "7:00 PM", "matters": "练习毛笔字" },
      { "index": 2, "time": "8:00 PM", "matters": "短距离夜骑" }
    ]
  },
  {
    "title": "周四的计划", "index": 4, "todoItems": [
      { "index": 1, "time": "7:00 PM", "matters": "运动健身" },
      { "index": 2, "time": "8:00 PM", "matters": "高数学习" }
    ]
  },
  {
    "title": "周五的计划", "index": 5, "todoItems": [
      { "index": 1, "time": "7:00 PM", "matters": "云顶之奕" }
    ]
  },
  {
    "title": "周六的计划", "index": 6, "todoItems": [
      { "index": 1, "time": "7:00 AM", "matters": "绿道骑行" },
      { "index": 2, "time": "7:00 PM", "matters": "线代学习" }
    ]
  },
  {
    "title": "周日的计划", "index": 7, "todoItems": [
      { "index": 1, "time": "8:00 AM", "matters": "学习,整理,总结" },
      { "index": 2, "time": "3:00 PM", "matters": "追番,追剧,追综艺" }
    ]
  }
]
  • 在 components 文件夹下创建 TodoItems.js 文件,WeekPlan.js 文件:
javascript 复制代码
// TodoItems.js 
import React from "react";
​
const TodoItems = ({ todoItems }) => (
    <ul>
        { todoItems.map(item => (
                /* 定义标签 class 属性时,JSX 中要用 className,因为 class 是 JavaScript 声明 类的保留字 */
                <li clsssName="todo-item" key={item.index}>{ `${item.time}:${item.matters}` }</li>
            )
        )}
    </ul>
);
​
export default TodoItems;
javascript 复制代码
// WeekPlan.js
import React from "react";
import TodoItems from "./TodoItems";
​
const WeekPlan = ({ weekPlanList }) => (
    weekPlanList.map(weekPlan => (
        <React.Fragment key={weekPlan.index}>
            <h2>{weekPlan.title.replace('的', '') + ':'}</h2>
            <TodoItems {...weekPlan} />
        </React.Fragment>
    ))
);
​
export default WeekPlan;

在组件中,导出用 export,导入组件用 import,这里我们可以拓展一下

  • export:主要用于暴露文件部分对象,且可以同时暴露多个。

  • export default:暴露文件内部所有对象。

  • import {} from "...": 接受 export 暴露的所有对象,接受对象的名称不能自定义,但可以接 as 来自定义对象名称。

  • import customName form "...": custTomName 可以为自定义名称。

  • 来看个例子就很好理解了:

javascript 复制代码
// exportExample.js
export const author = "export:炭烤小橙微辣";

const getAuthor = () => {
  return `export default: ${author}`;
};

export default getAuthor;
javascript 复制代码
import { author } from "./exportExample";
import getAuthor from "./exportExample";
import getAuthorByExample from "./exportExample";
import { author as authorAs } from "./exportExample";
import * as authorByAll from "./components/test";
​
console.log(author); // export:炭烤小橙微辣
console.log(getAuthor()); // export default:炭烤小橙微辣
console.log(getAuthorByExample()); // export default:炭烤小橙微辣
console.log(authorAs); // export:炭烤小橙微辣
console.log(authorByAll.author); // export:炭烤小橙微辣

module.exports 的导出与导入请看前边的文章《JavaScript 新特性》,这里就不再多赘述了。

  • 在 src 目录下创建 index.html 文件:
html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>周计划</title>
</head>
<body>
 <div id="root"></div>
</body>
</html>
  • 在 src 目录下创建 index.js 文件:
javascript 复制代码
import React from "react";
import { createRoot } from "react-dom/client";
import WeekPlan from "./components/WeekPlan";
import planList from "./originalData/planList.json"

const root = createRoot(document.getElementById("root"));
root.render(<WeekPlan weekPlanList={planList} />);

把组件,数据文件都配置好了,就可以配置 webpack 打包的相关配置了。

我们安装 webpack,webpack-cli,在项目定义webpack版本,这样,webpack

css 复制代码
npm install webpack webpack-cli --save-dev

局部安装:对项目定义 webpack 版本,打包的时候就不会出现包版本的问题了。

webpack-cli 是 webpack 的执行依赖,在 webpack-cli 中代码执行时,才是 webpack 进行编译和打包的过程。

那么 webpack 是怎样进行项目打包的呢?

当我们运行webpack时, webpack 会 查找当前目录下的 src/index.js 作为入口,然后从入口开始,会生成一个依赖关系图,这个关系图包含程序中所需的模块(js,css,图片等)然后历遍结构,打包一个个模块,其中会用到 loader 来解析不同文件来进行相应的解析。

我们知道 JSX 等文件需要编译才能被浏览器识别,这个时候有一个 叫做 Babel 的转换器,我们先安装 Babel 依赖:

sql 复制代码
npm install babel-loader @babel/core --save-dev

安装 babel 预设:提前定义 bable 把 JSX,ESNext 语句转换成什么类型的语句。

sql 复制代码
npm install @babel/preset-env @babel/preset-react --save-dev

我们在根目录新建一个 .babelrc 文件: 这个文件主要就是为 babel 提供编译规则,presets 数组中,越靠后的越先执行;

perl 复制代码
// .babelrc
{
  "presets": ["@babel/preset-env", "@babel/preset-react"]
}

下边对这几个插件及依赖进行一个简单的介绍:

  • babel-loader: 解析 ESNext,JSX 等语句的桥梁。
  • @babel/core: 根据(.babelrc)中的规则,进行源码的转换。
  • @babel/preset-env:提供 ESNext 转换为 ES5 的语法转换规则。
  • @babel/preset-react: 对react语法的转换。

Babel 功能及其强大,对于 Babel 的详细介绍,感兴趣的 jym 可以看看 Babel的文档

最后一步,安装插件 html-webpack-plugin, webpack-serve-dev

css 复制代码
npm install html-webpack-plugin  webpack-serve-dev --save-dev

webpack-serve-dev: 本地开发工具,本地可以直接启用服务来查看页面。

在使用 webpack 构建时,我们需要把 JSX 转换成 React 元素。需要新建一个配置文件: webpack.config.js(自定义打包配置文件), 这个文件名字固定,webpack 打包之前会解析这个文件,以获取打包的自定义配置。

javascript 复制代码
// webpack.config.js
// path 为 Node.js 内置 npm 模块,只要为了更方便的处理文件或目录路径
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");

module.exports = {
    entry: "./src/index.js", // 项目入口
    devtool: "source-map", // 源码映射,方便使用源码调试
    output: {
        path: path.join(__dirname, "dist"), // 打包根目录下创建一个文件dist文件夹,里边是打包好的文件
        filename: "bundle.js" // 所有的 react,JSX,EXNext 代码 都将被编译打包进这个文件
    },
    module: {
        rules: [
            // 在所有导入的除 node_modules 文件夹中的 JavaScript 文件上运行 babel-loader
            {test: /.js$/, exclude: /node_modules/, loader: "babel-loader"}
        ]
    },
    plugins: [
        new HtmlWebpackPlugin({
            // 以public下index.html 为模版打包生成html文件, 打包的 js 文件 或其他 css 等文件,并在 这个文件中插入一个
            // script 标签,标签的地址就是上边的 output.filename
            template: path.resolve(__dirname, 'src/index.html')
        })
    ]
}

最后配置 package.json 中的 scirpts 对象:

bash 复制代码
{
  "test": "echo "Error: no test specified" && exit 1",
  "build": "webpack --mode production",
  "dev": "webpack --mode develoment",
  "start": "webpack-dev-server --open --mode development"
}

现在所有配置都已完成,现在想看到自己写的周计划项目的话,只需要在终端 输入命令:

arduino 复制代码
npm run start

等服务启动成功,就可以在浏览器地址为 http://localhost:8080/ 的页面看到自己写的周计划啦!

我们可以把项目打包到 dist 文件夹下,执行如下命令:

arduino 复制代码
npm run build

经过打包过后,就多出来一个 dist 文件夹,里边的也就是打包过后的文件。

总结

我们这么大费周章的通过对 webpack,Babel 等工具的简单介绍,然后一步一步创建一个 React 应用,目的其实很简单,就是希望大家对从头创建一个 React 项目有所了解,虽然现在有更便捷创建 React 应用的方式,但是,这就是创建一个 React 项目的基础,当然,要创建一个应用级的项目,这些配置肯定是不够的,里边还有很多需要配置,比如 ESlint,router,state 等等,这也算是一个抛砖引玉的过程吧。

拓展: 作为一个 React 开发者, Create React App 这个工具能够帮助开发者快速创建 React 项目。 可以全局安装 Create React App包(不想安装:直接执行 npx create-react-app my-project):

lua 复制代码
npm install create-react-app -g

安装成功后,就可以通过这个包来创建更加健全的 React 应用了。

lua 复制代码
create-react-app my-project
相关推荐
恋猫de小郭13 小时前
Flutter Zero 是什么?它的出现有什么意义?为什么你需要了解下?
android·前端·flutter
崔庆才丨静觅19 小时前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby606120 小时前
完成前端时间处理的另一块版图
前端·github·web components
掘了20 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅20 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅21 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅21 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment21 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅21 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊21 小时前
jwt介绍
前端