上篇文章学习了webpack的基础知识,这次就一起动手来搭建一个简单的react工程吧~
首先使用命令行创建一个新工程
mkdir react-demo
cd react-demo
npm init -y // 把所有预置项都配置成npm默认的配置项
下来我们安装基础依赖,webpack从4开始就将webpack和webpack-cli分开处理了,所以需要分开安装
npm install react react-dom // 高版本的npm,所以不指定-s参数,也能顺利写入
npm install webpack -D
npm install webpack-cli -D
然后我们在工程中新建src文件夹,并在src文件加下创建App.js文件,将该文件挂载在id为app的dom上:
import React from 'react';
import ReactDom from 'react-dom';
const App = () => {
return (
<div>
<h1>React大法好</h1>
</div>
)
}
export default App;
ReactDom.render(<App/>, document.getElementById('app'));
在src文件夹下创建index.html文件,写入id为app的dom
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>React Webpack测试</title>
</head>
<body>
<div id="app"></div>
</body>
</html>
这个时候我们会遇到两个问题
- const App => {},这是一个ES6语法,webpack只能处理ES5及以下版本的js,所以这时候直接打包会报错
- html文件在webpack当中应该怎么处理呢?
首先解决第一个问题,如何将ES6语法代码转换成较低版本的ES语法代码,那这个时候就需要引入babel来进行编译
npm install @babel/core @babel/cli
在项目中新建一个test.js文件(后期可删除),写一段ES6语法:
[1, 2, 3].map(item => {
console.log(item);
})
然后看看该ES6代码如何变成ES5的代码,命令行输入
babel test.js
// 结果为
// [1, 2, 3].map(item => {
// console.log(item);
// });
那我们引入了babel之后,为什么还是ES6语法的样子呢?原来是因为我们没有加转换规则,我们继续安装转换规则
// preset-env核心语法将高版本ES语法转换成低版本
npm install @babel/preset-env
下面再来试试,此时注意,在进行编译的同时我们需要指定规则
babel test.js --presets=@babel/preset-env
// 结果为
// [1, 2, 3].map(function (item) {
// console.log(item);
// });
看到这时已经成功将ES语法转换成低版本,这里强调一下,babel除了可以用命令行来做配置文件之外,还可以像webpack一样支持配置文件,有以下两种形式:
- 可以直接放在package.json里面
"dependencies": {
"@babel/preset-env": "^7.12.10"
},
"babel": {
"presets": ["@babel/preset-env"] // 在此处指定规则
}
- .babelrc的配置文件(react-demo下新建一个.babelrc文件)
{
"presets": ["@babel/preset-env"]
}
以上两种形式是等价的,但是babel在转义的时候会优先去查找.babelrc文件,如果不存在,才会考虑其他的路径。
下面再考虑我们如何在react项目里使用babel呢?要把一种代码编译成另一种代码,是在文件维度的动作,loader正是对文件进行操作,所以我们这里使用loader,在react-demo文件夹下新建webpack.config.js文件:
module.exports = {
module: {
rules: [
{
test: /\.jsx?/, // 即匹配了js文件又匹配了jsx文件
// 将node_modules排除在外,在编译过程中,不仅编译了自己项目代码,还编译node_modules那么多不是自己写的代码,非常不利于webpack构建性能
exclude: /node_modules/,
use: {
loader: 'babel-loader'
}
}
]
}
}
此时不仅要对.js文件进行处理,还需要对.jsx文件进行处理,这时就需要安装babel/core、babel/cli、babel-loader
npm install @babel/core @babel/cli -D
npm install babel-loader -D
接下来继续配置babel规则
- 配置ES6相关规则
- 配置.jsx相关规则
然后我们需要安装@babel/preset-env规则的基础上再安装@babel/preset-react 规则
npm install @babel/preset-env @babel/preset-react -D
安装完成后,继续在webpack.config.js下配置规则
module: {
rules: [
{
use: {
loader: 'babel-loader',
options: {
babelrc: false, // 没有babelrc文件
presets: [
require.resolve('@babel/preset-react'),
require.resolve('@babel/preset-env', { modules: false })
// modules: false -> 模块化方案的一个指定,在编译ES6语法的时候,是否将import语法当做ES6语法进行编译
// webpack识别import和export,因为我们已经有了commonJS这个模块化方案,所以我们可以置为false
],
// 是否对编译结果做缓存
cacheDirectory: true,
}
}
}
]
}
}
接下来我们处理.html文件:
npm install html-webpack-plugin -D
在webpack.config文件中配置如下信息:
const HtmlWebpackPlugin = require('html-webpack-plugin');
const path = require('path');
module.exports = {
plugins: [
new HtmlWebpackPlugin({
template: path.resolve(__dirname, 'src/index.html'), // 需要被处理文件路径
filename: "index.html" // 文件打包完毕之后,目标文件名称
})
]
}
此时我们发现jsx文件只有输出,并没有引入,所以我们.jsx需要入口文件,在src文件夹下新建index.jsx文件
import App from './App';
webpack虽然有默认的入口文件,谨慎起见,还是需要写一下入口文件
module.exports = {
entry: path.resolve(__dirname, 'src/index.jsx'),
}
下来打包文件试试,因为我们现在仍处于开发阶段,所以模式设置为development,命令行输入:
webpack --mode development
此时可以看到打包成功!之后我们安装webpack-dev-server来启动看看是否成功
npm install webpack-dev-server -D
webpack-dev-server
启动项目之后报错了!
最后经过一番查找,我们需要将webpack-cli换到3版本,那这里我们就用3.3.12版本吧,安装之后再试试~
哈哈哈,终于成功了~在启动项目时也可以在package.json文件内配置自定义构建命令
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"dev": "webpack-dev-server --mode development --open" // --open 自动打开浏览器
}
配置自定义构建命令之后,我们运行npm run dev即可启动项目
做个扩展吧,那该项目如何做到热替换(HMR)?继续在webpack.config.js文件中修改devServer
const webpack = require('webpack');
plugins: [
new webpack.HotModuleReplacementPlugin()
],
devServer: {
hot: true
}
在入口文件index.jsx内添加
if (module.hot) {
module.hot.accept(error => {
if (error) {
console.log('热替换出bug了');
}
})
}
重启项目,简单修改一下你的代码,即可看到热更新效果啦~
这个项目比较简单,路由什么的都还没有加,有兴趣的同学后期可以添加呀?
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!