从零开始使用webpack搭建一个react项目

先做一个正常编译es6语法的webpack demo

1. 初始化package.json文件

npm init一路enter下去

2. 添加插件

{"name": "demo","version": "1.0.0","description": "","main": "index.js","scripts": {"test": "echo \"Error: no test specified\" && exit 1","devBuild": "cross-env NODE_ENV=development webpack --config build-splitChunks-react/webpack.config.js","start:dev": "cross-env NODE_ENV=development webpack-dev-server --config build-splitChunks-react/webpack.config.js","start:prod": "cross-env NODE_ENV=production webpack-dev-server --config build-splitChunks-react/webpack.config.js","build": "cross-env NODE_ENV=production webpack --config build-splitChunks-react/webpack.config.js"},"keywords": [],"author": "","license": "ISC","devDependencies": {"@babel/core": "^7.0.0","@babel/plugin-proposal-private-property-in-object": "^7.21.11","@babel/preset-env": "^7.22.20","@babel/preset-react": "^7.22.15","@babel/preset-typescript": "^7.23.0","@reduxjs/toolkit": "^1.9.7","@types/react": "^18.2.27","@types/react-dom": "^18.2.12","autoprefixer": "^9.7.3","axios": "^1.5.1","babel-core": "^7.0.0-bridge.0","babel-loader": "7","babel-preset-env": "^1.7.0","clean-webpack-plugin": "^3.0.0","cross-env": "^7.0.3","css-loader": "^3.2.1","file-loader": "^5.0.2","happypack": "^5.0.1","html-webpack-plugin": "^3.2.0","less": "^3.10.3","less-loader": "5.0.0","mini-css-extract-plugin": "^0.8.0","optimize-css-assets-webpack-plugin": "^5.0.3","postcss-loader": "^3.0.0","react-redux": "^8.1.3","redux": "^4.2.1","redux-persist": "^6.0.0","style-loader": "^1.0.1","terser-webpack-plugin": "^2.2.2","typescript": "^5.2.2","url-loader": "^3.0.0","webpack": "^4.41.2","webpack-cli": "^3.3.10","webpack-dev-server": "^3.9.0","webpack-merge": "^4.2.2","webpack-parallel-uglify-plugin": "^1.1.2"},"dependencies": {"antd": "^5.10.0","lodash": "^4.17.15","moment": "^2.24.0","react": "^18.2.0","react-dom": "^18.2.0"}
}

注意: babel相关插件最好是同一个数字版本开头的, 比如7.xx.xx, 因为页面报babel-loader编译问题, 提示是版本不一致

另外因为我使用了redux, 复杂的项目可以使用它, 简单的项目context或者recoil就行了, 按需下载, 不需要的可以卸载

3. react多页配置

1) webpack.common.js拆分公共部分

const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const { srcPath, distPath } = require('./paths')module.exports = {entry: {index: path.join(srcPath, 'index.tsx'),other: path.join(srcPath, 'other.tsx')},resolve: {extensions: ['.tsx', '.ts', '.jsx', '.js']},module: {rules: [{test: /.(jsx?)|(ts?x?)$/,loader: ['babel-loader'],include: srcPath,exclude: /node_modules/},]},plugins: [// 多入口 - 生成 index.htmlnew HtmlWebpackPlugin({template: path.join(srcPath, 'index.html'),filename: 'index.html',// chunks 表示该页面要引用哪些 chunk (即上面的 index 和 other),默认全部引用chunks: ['index', 'vendor', 'common']  // 要考虑代码分割}),// 多入口 - 生成 other.htmlnew HtmlWebpackPlugin({template: path.join(srcPath, 'other.html'),filename: 'other.html',chunks: ['other', 'common']  // 考虑代码分割})]
}

2) webpack.dev.js:

dev环境需要的webpack配置, 注意与webpack.common.js的逻辑进行合并

const path = require('path')
const webpack = require('webpack')
const webpackCommonConf = require('./webpack.common.js')
const { smart } = require('webpack-merge')
const { srcPath, distPath } = require('./paths')module.exports = smart(webpackCommonConf, {mode: 'development',module: {rules: [// 直接引入图片 url{test: /\.(png|jpg|jpeg|gif)$/,use: 'file-loader'},{test: /\.css$/,// loader 的执行顺序是:从后往前loader: ['style-loader', 'css-loader', 'postcss-loader'] // 加了 postcss},{test: /\.less$/,// 增加 'less-loader' ,注意顺序loader: ['style-loader', 'css-loader', 'less-loader']}]},plugins: [new webpack.DefinePlugin({// 'development''process.env': {NODE_ENV: JSON.stringify(process.env.NODE_ENV)}})],devServer: {port: 8111,progress: true,  // 显示打包的进度条contentBase: distPath,  // 根目录open: true,  // 自动打开浏览器compress: true,  // 启动 gzip 压缩// 设置代理proxy: {// 将本地 /api/xxx 代理到 localhost:3000/api/xxx'/api': 'http://localhost:8000',// 将本地 /api2/xxx 代理到 localhost:3000/xxx'/api2': {target: 'http://localhost:8111',pathRewrite: {'/api2': ''}}}}
})

3) webpack.production.js:

production环境需要的webpack配置, ,注意与webpack.common.js的逻辑进行合并

const path = require('path')
const webpack = require('webpack')
const { smart } = require('webpack-merge')
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const TerserJSPlugin = require('terser-webpack-plugin')
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin')
const webpackCommonConf = require('./webpack.common.js')
const { srcPath, distPath } = require('./paths')module.exports = smart(webpackCommonConf, {mode: 'production',output: {// filename: 'bundle.[contentHash:8].js',  // 打包代码时,加上 hash 戳filename: '[name].[contentHash:8].js', // name 即多入口时 entry 的 keypath: distPath,// publicPath: 'http://cdn.abc.com'  // 修改所有静态文件 url 的前缀(如 cdn 域名),这里暂时用不到},module: {rules: [// 图片 - 考虑 base64 编码的情况{test: /\.(png|jpg|jpeg|gif)$/,use: {loader: 'url-loader',options: {// 小于 5kb 的图片用 base64 格式产出// 否则,依然延用 file-loader 的形式,产出 url 格式limit: 5 * 1024,// 打包到 img 目录下outputPath: '/img1/',// 设置图片的 cdn 地址(也可以统一在外面的 output 中设置,那将作用于所有静态资源)// publicPath: 'http://cdn.abc.com'}}},// 抽离 css{test: /\.css$/,loader: [MiniCssExtractPlugin.loader,  // 注意,这里不再用 style-loader'css-loader','postcss-loader']},// 抽离 less{test: /\.less$/,loader: [MiniCssExtractPlugin.loader,  // 注意,这里不再用 style-loader'css-loader','less-loader','postcss-loader']}]},plugins: [new CleanWebpackPlugin(), // 会默认清空 output.path 文件夹new webpack.DefinePlugin({'process.env': {NODE_ENV: JSON.stringify(process.env.NODE_ENV)}}),// 抽离 css 文件new MiniCssExtractPlugin({filename: 'css/main.[contentHash:8].css'})],optimization: {// 压缩 cssminimizer: [new TerserJSPlugin({}), new OptimizeCSSAssetsPlugin({})],// 分割代码块splitChunks: {chunks: 'all',/*** initial 入口 chunk,对于异步导入的文件不处理async 异步 chunk,只对异步导入的文件处理all 全部 chunk*/// 缓存分组cacheGroups: {// 第三方模块vendor: {name: 'vendor', // chunk 名称priority: 1, // 权限更高,优先抽离,重要!!!test: /node_modules/,minSize: 0,  // 大小限制minChunks: 1  // 最少复用过几次},// 公共的模块common: {name: 'common', // chunk 名称priority: 0, // 优先级minSize: 0,  // 公共模块的大小限制minChunks: 2  // 公共模块最少复用过几次}}}}
})

4) 可以再加一个webpack.config.js文件:

根据环境判断是使用webpack.dev.js还是webpack.production.js

const prodConfig = require('./webpack.prod.js');const webpackConfig = process.env.NODE_ENV !== 'development' ? prodConfig : () => import('./webpack.dev.js');
module.exports = webpackConfig;

5) 在package.json添加如下命令:

"scripts": {"test": "echo \"Error: no test specified\" && exit 1","dev": "cross-env NODE_ENV=development webpack-dev-server --config build-splitChunks-react/webpack.config.js","buil:debv": "cross-env NODE_ENV=development webpack --config build-splitChunks-react/webpack.config.js","build": "cross-env NODE_ENV=production webpack --config build-splitChunks-react/webpack.config.js"},
cross-env改变process.env.NODE_ENV的值, 在控制台可以打印出来

console.log(process.env.NODE_ENV);

4. 新建index.html, index.tsx, other.html, other.tsx文件

index.tsx文件

// index.tsx
import React from 'react'
import ReactDOM from 'react-dom/client'
/*** 不加后缀.tsx的配置: 在module.exports对象中追加=>* resolve: {extensions: ['.js', '.jsx', '.tsx', '.ts']},*/
import App from './App';
const root = ReactDOM.createRoot(document.getElementById('root') as HTMLElement)
// v18 的新方法
root.render(<App />)

index.html

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>webpack demo</title>
</head>
<body><p>webpack demo</p><div id="root"></div>
</body>
</html>

other.tsx和other.html差不多一样按react要求写, 写出差异页面能够看出是不同页面就行

5. 新建.babelrc文件

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

6. 新建postcss.config.js文件

module.exports = {plugins: [require('autoprefixer')]
}

7. 新建tsconfig文件

{"compilerOptions": {"target": "es5","lib": ["dom","dom.iterable","esnext"],"allowJs": true,"skipLibCheck": true,"esModuleInterop": true,"allowSyntheticDefaultImports": true,"strict": true,"forceConsistentCasingInFileNames": true,"module": "esnext","moduleResolution": "node","resolveJsonModule": true,"isolatedModules": true,"noEmit": true,"jsx": "react-jsx","noImplicitAny": false},"include": ["src"]
}

5. Test组件

import React, { useEffect, useState } from "react";
import _ from "lodash";const Test = () => {const [data, setData] = useState({ a: "hello world" });useEffect(() => {setData({ a: "gggg" });console.log("process", process.env.NODE_ENV, process.env);}, []);return <div>{_.get(data, "a")}</div>;
};export default Test;

6. 在App.tsx组件中引入Test组件测试效果

import React, { Suspense, lazy } from "react";
import { Spin } from "antd";
import Test from "./Test";const App: React.FC = () => {return (<Suspense fallback={<Spin />}><Test /></Suspense>);
};export default App;

index.html效果图如下:

other.html效果图如下:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/104201.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

《RISC-V体系结构编程与实践》的benos_payload程序——mysbi跳转到benos分析

1、benos_payload.bin结构分析 韦东山老师提供的开发文档里已经对程序的结构做了分析&#xff0c;这里不再赘述&#xff0c;下面是讨论mysbi跳转到benos的问题&#xff1b; 2、mysbi跳转到benos的代码 3、跳转产生的疑问 我认为mysbi.bin最后跳转到0x22000地址处执行&#xff0…

Pytorch从零开始实战05

Pytorch从零开始实战——运动鞋识别 本系列来源于365天深度学习训练营 原作者K同学 文章目录 Pytorch从零开始实战——运动鞋识别环境准备数据集模型选择数据可视化模型预测总结 环境准备 本文基于Jupyter notebook&#xff0c;使用Python3.8&#xff0c;Pytorch2.0.1cu118…

代码混淆界面介绍

代码混淆界面介绍 代码混淆功能包括oc&#xff0c;swift&#xff0c;类和函数设置区域。其他flutter&#xff0c;混合开发的最终都会转未oc活着swift的的二进制&#xff0c;所以没有其他语言的设置。 代码混淆功能分顶部的显示控制区域&#xff1a;显示方式&#xff0c;风险等…

centos7安装db2 version11.1

centos7安装DB2 操作系统 linux centos7 DB2版本 11.1 1、取包 IBM MRS Tool 将安装包放在 /home/software 下面 mkdir -p /home/software cd /home/software wget https://iwm.dhe.ibm.com/sdfdl/v2/regs2/db2pmopn/Express-C/DB2ExpressC11/Xa.2/Xb.aA_60_-i7wWKFMFpbW1xl1…

高压放大器在软体机器人领域的应用

软体机器人是一种新型机器人技术&#xff0c;与传统的硬体机器人有着很大的不同。软体机器人通常由柔软的材料制成&#xff0c;具有高度的柔韧性和灵活性&#xff0c;并且可以实现多种形状和动作。但是&#xff0c;软体机器人的发展面临很多技术挑战&#xff0c;其中之一就是控…

Java 解析 cURL(bash) 命令

解析 cURL&#xff08;bash&#xff09; 命令 1. 主要用于解析从浏览器复制来的 cURL(bash)2. 废话不多说&#xff0c;都在&#x1f37b;代码里了。参考资料 1. 主要用于解析从浏览器复制来的 cURL(bash) curl https://eva2.csdn.net/v3/06981375190026432f77c01bfca33e32/lts/…

使用PyQt5创建图片查看器应用程序

使用PyQt5创建图片查看器应用程序 作者&#xff1a;安静到无声 个人主页 在本教程中&#xff0c;我们将使用PyQt5库创建一个简单的图片查看器应用程序。这个应用程序可以显示一系列图片&#xff0c;并允许用户通过按钮切换、跳转到不同的图片。 1. 准备工作 首先&#xff0…

在 TensorFlow 中调试

如果调试是消除软件错误的过程&#xff0c;那么编程一定是添加错误的过程。Edsger Dijkstra。来自 https://www.azquotes.com/quote/561997 一、说明 在这篇文章中&#xff0c;我想谈谈 TensorFlow 中的调试。 在之前的一些帖子&#xff08;此处、此处和此处&#xff09;中&…

谜题(Puzzle, ACM/ICPC World Finals 1993, UVa227)

有一个5*5的网格&#xff0c;其中恰好有一个格子是空的&#xff0c;其他格子各有一个字母。一共有4种指令&#xff1a;A, B, L, R&#xff0c;分别表示把空格上、下、左、右的相邻字母移到空格中。输入初始网格和指令序列&#xff08;以数字0结束&#xff09;&#xff0c;输出指…

Linux shell编程学习笔记11:关系运算

Linux Shell 脚本编程和其他编程语言一样&#xff0c;支持算数、关系、布尔、字符串、文件测试等多种运算。前面几节我们研究了 Linux shell编程 中的 字符串运算 和 算术运算&#xff0c;今天我们来研究 Linux shell编程中的的关系运算。 一、关系运算符功能说明 运算符说明…

go语言基础之变量

目录 视频学习地址&#xff1a;Go零基础入门_在线视频教程-CSDN程序员研修院 一. 单变量声明和赋值 1、变量的声明 2、变量赋值 3、声明并赋值 二. 多变量声明和赋值 1、多变量声明 2、多变量赋值 三. 变量声明赋值的简易写法 1、单变量简易写法 2、多变量简易写法 …

DOSBox和MASM汇编开发环境搭建

DOSBox和MASM汇编开发环境搭建 1 安装DOSBox2 安装MASM3 编译测试代码4 运行测试代码5 调试测试代码 本文属于《 X86指令基础系列教程》之一&#xff0c;欢迎查看其它文章。 1 安装DOSBox 下载DOSBox和MASM&#xff1a;https://download.csdn.net/download/u011832525/884180…

uniapp封装loading 的动画动态加载

实现效果 html代码 <view class"loadBox" v-if"loading"><img :src"logo" class"logo"> </view> css代码 .loadBox {width: 180rpx;min-height: 180rpx;border-radius: 50%;display: flex;align-items: center;j…

【面试经典150 | 哈希表】存在重复元素 II

文章目录 Tag题目来源题目解读解题思路方法一&#xff1a;哈希表方法二&#xff1a;滑动窗口 其他语言python3哈希表python3滑动窗口 写在最后 Tag 【哈希表】【滑动窗口】【数组】 题目来源 219. 存在重复元素 II 题目解读 判断在数组中有没有相同的元素小于一定的距离。 解…

Win10 系统中用户环境变量和系统环境变量是什么作用和区别?

环境&#xff1a; Win10专业版 问题描述&#xff1a; Win10 系统中用户环境变量和系统环境变量是什么作用和区别&#xff1f; 解答&#xff1a; 在Windows 10系统中&#xff0c;用户环境变量和系统环境变量是两个不同的环境变量&#xff0c;它们具有不同的作用和区别 1.用…

【Debian】报错:su: Authentication failure

项目场景&#xff1a; 今天我重新刷了一个debian系统。 系统版本&#xff1a; # 查看系统版本 lsb_release -a 我的系统版本&#xff1a; No LSB modules are available. Distributor ID&#xff1a;Debian Description: Debian GNU/Linux 12 &#xff08;bookworm&#xff…

目录启示:PHP 与命名空间的声明

文章目录 参考环境命名空间概念版本支持影响范围 全局命名空间概念魔术常量 \_\_NAMESPACE\_\_声明全局命名空间 声明命名空间为空间命名命名规则核心命名空间 子命名空间的声明在同一文件中定义多个命名空间无括号命名空间声明有括号命名空间声明禁止混合使用推荐使用有括号命…

统信UOS1060设置自动关机01

原文链接&#xff1a;统信UOS1060设置自动关机01 hello&#xff0c;大家好啊&#xff0c;今天给大家介绍一篇如何在统信UOS 1060上实现自动关机的文章&#xff0c;本篇文章采用两种方式&#xff0c;第一种使用的是crontab定时任务的方式&#xff0c;第二种是使用at命令的方式&a…

实体解析实施的复杂性

实体的艺术表现斯特凡伯克纳 一、说明 实体解析是确定数据集中的两条或多条记录是否引用同一现实世界实体&#xff08;通常是个人或公司&#xff09;的过程。乍一看&#xff0c;实体分辨率可能看起来像一个相对简单的任务&#xff1a;例如&#xff0c;给定一张人物的两张照片&a…

natapp内网穿透-将本地运行的程序/服务器通过公网IP供其它人访问

文章目录 1.几个基本概念1.1 局域网1.2 内网1.3 内网穿透1.4 Natapp 2.搭建内网穿透环境3.本地服务测试 1.几个基本概念 1.1 局域网 LAN&#xff08;Local Area Network&#xff0c;局域网&#xff09;是一个可连接住宅&#xff0c;学校&#xff0c;实验室&#xff0c;大学校…