webpack构建自定义react应用

简介: 在上一篇文章中我们用webpack与webpack-cli搭建了最简单的前端应用,通常在项目中我们会用vue或者react,我们看下如何利用我们自己搭的工程来适配react

上一篇文章中我们用webpackwebpack-cli搭建了最简单的前端应用,通常在项目中我们会用vue或者react,我们看下如何利用我们自己搭的工程来适配react


正文开始...


前置


首先我们要确定,react并不是在webpack中像插件一样安装就可以直接使用,我们需要支持jsx以及一些es6的一些比较新的语法,在creat-react-app这个脚手架中已经帮我们高度封装了react项目的一些配置,甚至你是看不到很多的配置,比如@babel/preset-react转换jsx等。所以我们需要知道一个react项目需要哪些插件的前提条件,本文主要参考从头开始打造工具链[1]


安装babel相关插件

npm i @babel/core @babel/cli @babel/preset-env @babel/preset-react --save

其中babel/core就是能将代码进行转换,@babel/cli允许命令行编译文件,babel/preset-env@babel/preset-react[2]都是预设环境,把一些高级语法转换成es5


安装好相关插件后,我们需要在根目录中创建一个.babelrc来让babel通知那两个预设的两个插件生效

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

接下来我们需要安装在react中的支持的jsx,主要依赖babel-loader来编译jsx

npm i babel-loader --save-dev

并且我们需要改下webpack.config.jsloader

{
  module: {
    rules: [
      {
        test: /\.css$/,
        use: ['style-loader', 'css-loader']
      },
      {
        test: /\.(png|svg|jpg|gif|jpeg)$/,
        use: [
          {
            loader: 'file-loader',
            options: {
              outputPath: 'assets',
              name: '[name].[ext]?[hash]'
            }
          }
        ]
      },
      {
        test: /\.(js|jsx)$/,
        loader: 'babel-loader',
        exclude: /node_modules/,
        options: {
          presets: ['@babel/env']
        }
      }
    ]
  },
}

react中我们设置HMR,我们需要结合new webpack.HotModuleReplacementPlugin(),并且在devServer中设置hottrue

module.exports = {
 ...
 plugins: [
    new HtmlWebpackPlugin({
      template: './public/index.html'
    }),
    new miniCssExtractPlugin({
      filename: 'css/[name].css'
    }),
    new webpack.HotModuleReplacementPlugin()
  ],
  devServer: {
      hot: true
  }
}

完整的配置webpack.config.js就已经ok了

// webpack.config.js
const path = require('path');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const miniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
  mode: 'development',
  entry: {
    app: './src/app.js'
  },
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: '[name].bundle.js'
  },
  module: {
    rules: [
      {
        test: /\.css$/,
        use: ['style-loader', 'css-loader']
      },
      {
        test: /\.(png|svg|jpg|gif|jpeg)$/,
        use: [
          {
            loader: 'file-loader',
            options: {
              outputPath: 'assets',
              name: '[name].[ext]?[hash]'
            }
          }
        ]
      },
      {
        test: /\.(js|jsx)$/,
        loader: 'babel-loader',
        options: {
          presets: ['@babel/env']
        }
      }
    ]
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: './public/index.html'
    }),
    new miniCssExtractPlugin({
      filename: 'css/[name].css'
    }),
    new webpack.HotModuleReplacementPlugin()
  ],
  devServer: {
    hot: true
  }
};

安装reactreact-dom这两个核心库

npm i react react-dom --save-dev

src目录下新建一个App.jsx

// App.jsx
import React, {Component} from 'react';
import deepMerge from './utils/index.js';
import '../src/assets/css/app.css';
import image1 from '../src/assets/images/1.png';
import image2 from '../src/assets/images/2.jpg';
class App extends Component {
  constructor(props) {
    super(props)
    this.state = {
      text: 'hello webpack for react',
      name: "Maic",
      age: 18,
      publicName: 'Web技术学苑',
      imgSource: [image1, image2]
    }
  }
  render() {
    const { text, name, age, publicName, imgSource} = this.state;
    return (<>
      <div className="app">
          <h1>{text}</h1>
          <div>
            <p>{name}</p>,<span>{age}</span>岁
            <p>{publicName}</p>
          </div>
          <div>
            {
              imgSource.map(src => <img src={src} key={src} />)
            }
          </div>
      </div>
    </>)
  }
}
export default App

我们在app.js中引入App.jsx

// app.js
import React from 'react';
import { createRoot } from 'react-dom/client';
import App from './App.jsx';
const appDom = document.getElementById('app');
const root = createRoot(appDom);
root.render(<App />);

我们运行npm run server,浏览器打开localhost:8080


好了,用webpack搭建一个自己的react应用就已经ok了


总结


1、react需要的一些插件,@babel/core@babel/cli@babel/preset-env@babel/preset-reactbabel-loader


2、设置.babelrc


3、引入reactreact-dom,modules中设置babel-loader编译jsx文件


4、本文code-example[3]


相关文章
|
前端开发 JavaScript NoSQL
使用 Node.js、Express 和 React 构建强大的 API
本文详细介绍如何使用 Node.js、Express 和 React 构建强大且动态的 API。从开发环境搭建到集成 React 前端,再到利用 APIPost 高效测试 API,适合各水平开发者。内容涵盖 Node.js 运行时、Express 框架与 React 库的基础知识及协同工作方式,还涉及数据库连接和前后端数据交互。通过实际代码示例,助你快速上手并优化应用性能。
|
编解码 前端开发 开发者
React 图片组件样式自定义:常见问题与解决方案
在 React 开发中,图片组件的样式自定义常因细节问题导致布局错乱、性能损耗或交互异常。本文系统梳理常见问题及解决方案,涵盖基础样式应用、响应式设计、加载状态与性能优化等,结合代码案例帮助开发者高效实现图片组件的样式控制。重点解决图片尺寸不匹配、边框阴影不一致、移动端显示模糊、加载失败处理及懒加载等问题,并总结易错点和最佳实践,助力开发者提升开发效率和用户体验。
534 22
|
Web App开发 移动开发 前端开发
React 视频播放器样式自定义实战指南
本文详细介绍了如何在React项目中实现视频播放器的样式自定义,涵盖HTML5 `&lt;video&gt;`标签的基础知识、CSS样式定制技巧及常见问题解决方案。针对全屏模式样式失效、移动端触摸事件冲突和进度条样式定制等问题提供了具体代码示例。同时,探讨了视频预加载策略和内存优化方法,并推荐了几款调试工具,帮助开发者提升用户体验和应用性能。
457 6
|
Web App开发 移动开发 前端开发
React音频播放器样式自定义全解析:从入门到避坑指南
在React中使用HTML5原生&lt;audio&gt;标签时,开发者常面临视觉一致性缺失、样式定制局限和交互体验割裂等问题。通过隐藏原生控件并构建自定义UI层,可以实现完全可控的播放器视觉风格,避免状态不同步等典型问题。结合事件监听、进度条拖拽、浏览器兼容性处理及性能优化技巧,可构建高性能、可维护的音频组件,满足跨平台需求。建议优先使用成熟音频库(如react-player),仅在深度定制需求时采用原生方案。
579 12
|
前端开发 JavaScript 开发者
使用React和Redux构建高效的前端应用
使用React和Redux构建高效的前端应用
304 2
|
前端开发 JavaScript Android开发
掌握React Native,构建跨平台移动应用的利器
掌握React Native,构建跨平台移动应用的利器
|
前端开发 JavaScript API
React Native实战:构建跨平台移动应用
React Native实战:构建跨平台移动应用
305 0
|
前端开发 JavaScript 网络架构
从零开始构建你的第一个React应用
从零开始构建你的第一个React应用
192 0
|
前端开发 JavaScript
webpack+react+redux+es6开发模式
一、预备知识   node, npm, react, redux, es6, webpack 二、学习资源   ECMAScript 6入门   React和Redux的连接react-redux   Redux 入门教程   redux middleware 详解   Redux研究   React 入门实例教程   webpack学习demo   NPM 使用介绍 三、工程搭建   之前有写过 webpack+react+es6开发模式 ,文章里介绍了一些简单的配置,欢迎访问。
1433 0
|
设计模式 前端开发 数据可视化
【第4期】一文了解React UI 组件库
【第4期】一文了解React UI 组件库
962 0