前端基础之《React(3)—webpack简介-集成JSX语法支持》

接上篇......

十一、集成JSX语法

1、安装react

bash 复制代码
cnpm i react -S
cnpm i react-dom -S

说明:

(1)-S是代码需要的包,-D是环境需要的包

(2)react-dom是用于挂载的

(3)react作用是用来封装组件的

2、建立react根组件

在src/App.jsx

javascript 复制代码
import React from 'react'

class App extends React.Component {
    render() {
        return (
            <div>
                <h1>Hello React</h1>
            </div>
        )
    }
}

export default App

3、main.js创建挂载节点

javascript 复制代码
// 入口文件
import { createRoot } from 'react-dom/client'
import App from './App.jsx'

const root = createRoot(document.getElementById('app'))
root.render(<App />)

4、babel安装react预设

bash 复制代码
cnpm i @babel/preset-react -D

babel.config.js:

javascript 复制代码
// 定义babel的工作方式
module.exports = {
    // 预设:用于编译哪些比较大的JS版本,比如ES6、TS、Flow、Vue等
    presets: [
        '@babel/preset-env',
        '@babel/preset-react' // 用于编译JSX语法
    ],
    // 插件
    plugins: [
        // 这个插件用于编译装饰器语法
        ["@babel/plugin-proposal-decorators", { "version": "2023-11" }]
    ]
}

5、babel-loader增加jsx配置

config.js:

javascript 复制代码
// 两个环境都需要的公共配置

// 从node进程中引入path模块
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const { ProgressPlugin } = require('webpack') // webpack自带插件

module.exports = {
    entry: {
        // 可以给入口文件取个名字,给output使用
        app: path.resolve(__dirname, '../', 'src/main.js'),
    },

    // 出口
    output: {
        // 自定义打包结果的输出目录,默认是dist目录,这里只能使用绝对路径
        path: path.resolve(__dirname, '../', 'dist'),
        // 指定打包结果的JS名称规范
        // filename: 'bundle.js' // 量词,一捆、一束
        filename: 'js/[name].[chunkhash:8].js',
        // 每次build打包时,都自动先删除dist中的旧文件
        clean: true
    },

    // 插件
    // 所有webpack插件都是class,用的时候需要new
    plugins: [
        // 用于把JS脚本和index.html自动注入合并
        new HtmlWebpackPlugin({
            template: path.resolve(__dirname, '../', 'public/index.html'),
            inject: 'body', // 把JS注入到body结束标签前面
            filename: 'index.html', // 指定打包成功后这个模板叫什么名字
            title: '测试'
        }),
        // 添加编译进度条
        new ProgressPlugin({
            handler(percentage, message, ...args) {
                console.log(percentage, message, ...args)
            }
        })
    ],

    // 在webpack眼中一切文件皆模块,webpack必须使用各种loaders来处理各种不同的模块文件
    module: {
        // 定义模块编译的规则和方式
        rules: [
            {
                test: /\.(js|jsx|ts|tsx)$/, // 检测模块以js结尾
                use: ['babel-loader'] // 使用babel编译器把ES6+的代码编译成ES5
            }
        ]
    }
}

修改:test: /\.(js|jsx|ts|tsx)$/, // 检测模块以js结尾

6、解决报错信息是编译后的行数

希望调试控制台中报错的位置和src源码位置保持一致。

serve.js:

javascript 复制代码
// 只有开发环境才需要用到配置
module.exports = {
    mode: 'development',
    devtool: 'inline-source-map',

    // 本地服务配置
    devServer: {
        port: 8000
    }
}

build.js:

javascript 复制代码
// 只有打包时才用到配置
module.exports = {
    mode: 'production',
    devtool: 'source-map'
}

重启服务,这时报错信息行数变成代码的行数了,而不是编译后的行数:

调试控制台:

inline-source-map

打包环境:

source-map

7、解决react没有导入问题

问题:为什么react没有导入?凡是用到JSX的地方,都要导入react

临时解决:import React from 'react'

背后原理:

(1)因为我们用到了jsx语法,jsx要编译成js代码,浏览器才能看的懂

(2)@babel/preset-react它要使用React.createElement()方法进行编译

(3)以后新建jsx文件天天都要导入吗?

(4)把React放在window上,全局上

8、把React放在全局上

使用内置插件ProvidePlugin

config.js:

javascript 复制代码
// 两个环境都需要的公共配置

// 从node进程中引入path模块
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const { ProgressPlugin, ProvidePlugin } = require('webpack') // webpack自带插件

module.exports = {
    entry: {
        // 可以给入口文件取个名字,给output使用
        app: path.resolve(__dirname, '../', 'src/main.js'),
    },

    // 出口
    output: {
        // 自定义打包结果的输出目录,默认是dist目录,这里只能使用绝对路径
        path: path.resolve(__dirname, '../', 'dist'),
        // 指定打包结果的JS名称规范
        // filename: 'bundle.js' // 量词,一捆、一束
        filename: 'js/[name].[chunkhash:8].js',
        // 每次build打包时,都自动先删除dist中的旧文件
        clean: true
    },

    // 插件
    // 所有webpack插件都是class,用的时候需要new
    plugins: [
        // 用于把JS脚本和index.html自动注入合并
        new HtmlWebpackPlugin({
            template: path.resolve(__dirname, '../', 'public/index.html'),
            inject: 'body', // 把JS注入到body结束标签前面
            filename: 'index.html', // 指定打包成功后这个模板叫什么名字
            title: '测试'
        }),
        // 添加编译进度条
        new ProgressPlugin({
            handler(percentage, message, ...args) {
                console.log(percentage, message, ...args)
            }
        }),
        // 从node_modules中加载react包,将其放在全局变量React中,这样之后所有的文件模块都可以直接访问
        new ProvidePlugin({
            React: 'react'
        }),
    ],

    // 在webpack眼中一切文件皆模块,webpack必须使用各种loaders来处理各种不同的模块文件
    module: {
        // 定义模块编译的规则和方式
        rules: [
            {
                test: /\.(js|jsx|ts|tsx)$/, // 检测模块以js结尾
                use: ['babel-loader'], // 使用babel编译器把ES6+的代码编译成ES5
                exclude: /node_modules/, // 排除node_modules目录下的第三方包文件
            }
        ]
    }
}

exclude: /node_modules/, // 排除node_modules目录下的第三方包文件

相关推荐
哔哩哔哩技术16 小时前
2025年哔哩哔哩技术精选技术干货
前端·后端·架构
霍理迪16 小时前
CSS布局方式——定位
前端·css
星光不问赶路人16 小时前
TypeScript 架构实践:从后端接口到 UI 渲染数据流的完整方案
前端·vue.js·typescript
ttyyttemo16 小时前
Dagger技术的使用学习
前端
IT_陈寒16 小时前
Redis性能翻倍的5个关键策略:从慢查询到百万QPS的实战优化
前端·人工智能·后端
码界奇点16 小时前
基于React与TypeScript的后台管理系统设计与实现
前端·c++·react.js·typescript·毕业设计·源代码管理
cehuishi952717 小时前
python和arcgispro的实践(AI辅助编程)
服务器·前端·python
Summer不秃17 小时前
使用 SnapDOM + jsPDF 生成高质量 PDF (含多页分页, 附源码)
前端·javascript·vue.js·pdf·node.js
AC赳赳老秦17 小时前
工业互联网赋能智造:DeepSeek解析产线传感器数据驱动质量管控新范式
前端·数据库·人工智能·zookeeper·json·flume·deepseek
Student_Zhang17 小时前
一个管理项目中所有弹窗的弹窗管理器(PopupManager)
前端·ios·github