##2024/9/11 21:31:15:
webpack 手动打包 react 代码
https://github.com/qyzhizi/js-logical/tree/main/2024-09-11-my-react-app
从 0 创建项目
npm init
安装运行时依赖项
npm install react react-dom
安装开发依赖项
npm install -D esbuild-loader babel-loader webpack html-webpack-plugin webpack-cli
mkdir src
cd src
src 目录新建 index.js
import React from 'react';
import ReactDOM from 'react-dom';
const myElement = /*#__PURE__*/React.createElement("h1", null, "I Love JSX!");
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(myElement);
src 目录新建 index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>My React App</title>
</head>
<body>
<div id="root"></div>
<!-- <script src="bundle.js"></script> -->
</body>
</html>
根目录新建 webpack.config.js 并配置
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
// mode: 'development',
mode: 'production', // 使用生产模式
entry: './src/index.js', // 入口文件
output: {
// filename: 'bundle.js',
filename: '[name].[contenthash].js', // 使用内容哈希生成文件名
path: path.resolve(__dirname, 'dist'),
publicPath: '/', // 使得应用能够正确地加载资源
},
module: {
// rules: [
// {
// test: /\.js$/,
// exclude: /node_modules/,
// use: 'babel-loader', // 使用 raw-loader 作为普通加载器
// },
// ],
rules: [
{
test: /\.js$/,
loader: 'esbuild-loader',
options: {
// loader: 'jsx', // Remove this if you don't use JSX
target: 'es2015'
}
}
]
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html', // HTML 模板
}),
],
devtool: 'source-map', // 生成源映射文件
};
根目录配置 package.json 中的 scripts 项
"scripts": {
"build": "webpack"
},
根目录进行打包构建
npm run build
根目录启动静态服务器
npx http-server dist
dist 是之前打包输出的目录,如果没有安装 http-server ,可以执行 npm install http-server -g
表示全局安装 http-server
解释
:
webpack 打包下面的代码:
import React from 'react';
import ReactDOM from 'react-dom';
const myElement = /*#__PURE__*/React.createElement("h1", null, "I Love JSX!");
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(myElement);
index.html 需要包含 root
id
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>My React App</title>
</head>
<body>
<div id="root"></div>
<!-- <script src="bundle.js"></script> -->
</body>
</html>
webpack 打包的配置文件:
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
// mode: 'development',
mode: 'production', // 使用生产模式
entry: './src/index.js', // 入口文件
output: {
// filename: 'bundle.js',
filename: '[name].[contenthash].js', // 使用内容哈希生成文件名
path: path.resolve(__dirname, 'dist'),
publicPath: '/', // 使得应用能够正确地加载资源
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: 'babel-loader', // 使用 raw-loader 作为普通加载器
},
],
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html', // HTML 模板
}),
],
devtool: 'source-map', // 生成源映射文件
};
babel-loader
是关键,与 react 进行配合
这里不是 jsx 语法,也可以使用 esbuild-loader
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
// mode: 'development',
mode: 'production', // 使用生产模式
entry: './src/index.js', // 入口文件
output: {
// filename: 'bundle.js',
filename: '[name].[contenthash].js', // 使用内容哈希生成文件名
path: path.resolve(__dirname, 'dist'),
publicPath: '/', // 使得应用能够正确地加载资源
},
module: {
// rules: [
// {
// test: /\.js$/,
// exclude: /node_modules/,
// use: 'babel-loader', // 使用 raw-loader 作为普通加载器
// },
// ],
rules: [
{
test: /\.js$/,
loader: 'esbuild-loader',
options: {
// loader: 'jsx', // Remove this if you don't use JSX
target: 'es2015'
}
}
]
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html', // HTML 模板
}),
],
devtool: 'source-map', // 生成源映射文件
};
target: 'es2015' 这里可以使用 raw-loader 普通加载器吗?
不可以,raw-loader 是直接导入字符串,不会把需要的第三方模块也打包进来
如果你希望使用 raw-loader 加载 JavaScript 文件,记住它只会返回文件内容而不会执行代码或打包依赖项。如果你需要将 JavaScript 代码及其依赖项打包在一起,建议使用 esbuild-loader 或其他适合的加载器,而不是 raw-loader。
rules: [
{
test: /\.js$/,
loader: 'esbuild-loader',
options: {
// loader: 'jsx', // Remove this if you don't use JSX
target: 'es2015'
}
}
]