用webpack
、React
创建单页面应用开发环境。
使用pnpm
本项目使用pnpm
代替npm
作为包管理器。如果你没有用过pnpm
,可以用以下方式开始:
安装pnpm
:
npm install -g pnpm
常用的两个pnpm
命令示例:
csharp
# 以下相当于 npm install --save react
pnpm add react
# 以下相当于 npm install --save-dev webpack
pnpm add -D webpack
创建package.json
package.json
是node项目的依赖管理文件。
创建初始package.json
bash
mkdir runmix
cd runmix
pnpm init
package.json
内容如下:
swift
{
"name": "runmix",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC"
}
安装react
一个React浏览器项目,需要包含至少react
和react-dom
两个依赖包。
csharp
pnpm add react react-dom
pnpm可以一次添加多个依赖
写React代码
我们打开react官网,找一个最简单的示例,作为我们的React应用的入口文件代码。
创建src
源码目录和入口文件App.jsx
。
css
mkdir -p src
touch src/App.jsx
App.jsx
的内容如下:
javascript
function RunmixApp() {
return (
<div>
<h1>Welcome to RunmixApp</h1>
</div>
);
}
用react-dom
,将RunmixApp
渲染到浏览器。
javascript
import { createRoot } from 'react-dom/client'
function RunmixApp() {
// ...
}
createRoot(document.getElementById('root'), <RunmixApp />)
好了,这些代码,能直接在浏览器端运行吗?
不行。因为浏览器,只认识html
/js
/css
。而这只是一段jsx
代码,需要借助html
,并转换为javascript
,才可以运行到浏览器中。
而将jsx
转换成javascript
,并创建合适的html
代码,我们可以借助编译工具webpack
。
项目编译
这部分用到了webpack, babel, npx, 如果你完全不了解其背景知识,可能看着有点懵。不过,你仍然可以根据代码块中的命令及代码,走完流程。
安装编译工具webpack
。
csharp
pnpm add -D webpack webpack-cli
只要在命令行中运行
webpack
,就需要引入webpack-cli
webpack
是根据配置文件来决定工作流程,其默认配置文件是根目录下的webpack.config.js
。
创建webpack.config.js
(根目录下执行)
arduino
touch webpack.config.js
内容如下:
java
module.exports = {
entry: './src/App.jsx',
}
我们用npx
快捷地运行一下webpack
试试。
npx webpack
报错了。
提示webpack
不认识App.jsx
。这,是为啥呢?
webpack
本身只是一个编译工具框架,它依赖各种各样的loaders
和plugins
来处理不同的文件。没有指定处理.jsx
的loader
,webpack
就不认识以此为后缀的文件。
比如,编译不同后缀的文件,webpack
生态中使用不同的loader
。处理.scss
,需要scss-loader
,处理.jsx
,需要babel-loader
。当然,babel-loader
不仅仅可以处理.jsx
,babel
有自己的插件体系。
又比如,生成入口index.html
文件,常常使用html-webpack-plugin
。
接下来,我们为webpack.config.js
补充loader
和plugin
。
webpack.config.js
css
module.exports = {
module: {
rules: [
{
test: /\.jsx?$/i,
use: 'babel-loader'
}
]
}
}
为了让babel-loader
认识.jsx
文件,还需要给babel-loader
增加babel
配置。babel-loader
默认从根目录下的.babelrc
文件中读取项目的babel配置。
创建.babelrc
bash
touch .babelrc
内容如下:
perl
{
"presets": [
["@babel/preset-react", {"runtime": "automatic"}]
]
}
这里,我们需要给项目添加@babel/preset-react
依赖。
sql
pnpm add -D babel-loader @babel/preset-react
再次运行npx webpack
。可以看到生成了dist
目录,并且生成了main.js
文件,如下图所示:
我们还需要一个index.html
,可以自己在dist
目录创建一个。代码如下:
xml
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Runmix</title>
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1"></meta>
</head>
<body>
<script src="./main.js"></script>
</body>
</html>
在浏览器中打开index.html
。效果如下:
自动生成index.html
上面手动创建的html中,我们引入了固定名称的./main.js
。如果该文件名是变化的呢?(生产环境中经常需要静态资源如js/css/图片生态动态的名称,以避免错误的缓存)手动引入就不太合适了。
接下来,我们用webpack的html插件,自动生成index.html并引入js
文件。
安装html-webpack-plugin
依赖。
csharp
pnpm add -D html-webpack-plugin
修改webpack.config.js
,添加:
arduino
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
// 其他配置
plugins: [
new HtmlWebpackPlugin({
template: './public/index.html'
})
],
// 动态生成入口js文件名
output: {
filename: 'app.[contenthash:8].js'
}
}
添加模板文件./public/index.html
。
xml
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Runmix</title>
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1"></meta>
</head>
<body>
<div id="root></div>
</body>
</html>
再次运行npx webpack
,打开dis/index.html
,可以看到能动态引入js
文件了。如下图:
生成git项目
将该项目转换为一个git
项目,以便提交到github
/gitee
之类的仓库。
初始化git
csharp
git init
添加.gitignore
,忽略不希望提交的文件。
bash
touch .gitignore
内容如下:
csharp
dist/
package-lock.json
pnpm-lock.yaml
node_modules/
提交代码
sql
git add ./
git commit -m 'init project using react/webpack'
添加远端仓库
scss
git remote add origin git@github.com:runmix-dev/runmix.git
推送最新代码到github
css
git push --set-upstream origin main
章节源码
本章节完整源码:github.com/runmix-dev/...