webpack 学习从零到亿过程
适合小白从零到一搭建一个项目,虽然没有效果的截图但是知道跟随这个步骤流程走下去,你就会成功掌握打包的原理!
- 我们先初始化一个 node 项目
npm init
- 安装 webpack 包
npm install webpack webpack-cli --save-dev
- 写 webpack 配置文件 config/webpack.dev.config.js
- 安装了 path
npm i path -s -d
并新建了 webpack.dev.config.js 写入下面简单配置
const path = require("path");
module.exports = {
entry: "./src/index.js", // 入口文件路径
output: {
path: path.resolve(__dirname, "../", "dist"), // 输出目录路径
filename: "[name]-[hash]-main.js", // 输出文件名
},
mode: "production",
};
- 在 package.json 中添加下面执行脚本命令
"dev": "webpack-cli --config config/webpack.dev.config.js"
-
终端运行
npm run dev
出现 dist 文件和打包结果 -
安装了
npm install clean-webpack-plugin --save-dev
每次执行之后相对打包结果进行清空 -
package.json 中添加如下配置
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
plugins: [
new CleanWebpackPlugin(),
],
-
在此执行
npm run dev
可以发现里面的 dist 目录每次都会被删除之后再去添加 -
打包工作完成之后,我想使用 webpack 启动一个服务去访问我的资源要怎么做?
-
首先我们安装
npm install -D webpack-dev-server
然后我们需要去 package.json 中添加一个新的命令
"dev2": "webpack serve --config config/webpack.dev.config.js"
- 没错是同一个配置文件,你也可以换一个新的文件,在原有的基础上我们需要添加 devserver
{
// 其他配置,
devServer: {
static: {
directory: path.join(__dirname,'../', 'public'),
},// 服务器根目录
port: 3000, // 服务器端口号
open: true, // 自动打开浏览器
},
}
- 这个 static 为 webpack 5.* 版本的哈 这意思就是启动这个服务之后,将这个静态资源加载进去,了解 nginx 配置的人都明白,当我们启动一个 nginx,我们可以访问我们 nginx.config 文件中的那些静态资源,原理应该和这个差不多,我们先去根目录下创建一个 public 文件并写一个 index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
我是运行态
</body>
</html>
- 这样我们执行
npm run dev2
会发现自动打开http://localhost:3000/
端口且内容都已展示
❓:我们想将打包之后的 js 也加载进去,怎么去做呢?
💡:我们可以将我们打包之后的 js 文件输出文件名写为固定的 main.js,即如下:
{
output: {
path: path.resolve(__dirname, 'dist'), // 输出目录路径
filename: 'main.js', // 输出的JavaScript文件名
}
}
- 这样我们知道我们的打包 js 文件了,我们可以直接去我们的
html
中引入这个 js 即可
❓:如果我们打包的解决就是带有hash
值的呢,我们该如何解决
💡:我们可以使用一个插件html-webpack-plugin
这个插件可以将我们打包的文件自动加载进入我们的html
模版中,这样我们就不用再去手动给该html
中引入这个 js 文件了 - 我们先去
webpack.dev.config.js
文件中配置如下,在此运行npm run dev
即可
const HtmlWebpackPlugin = require("html-webpack-plugin");
{
plugins: [
new CleanWebpackPlugin(),
new HtmlWebpackPlugin({
template: './public/index.html', // HTML模板路径
}),
],
}
- 好了,我们基本的项目搭建已经完成了,接下来我们想在项目中使用 react 要怎么做呢?
- 首先我们需要安装
react
react-dom
执行
npm install react react-dom --save-dev
- 安装完成之后我们就可以引入
react
语法啦
// 我们在main.js中写如下代码 dom是挂在root节点下,所以我们还要去html中加入这个节点
//main.js
import React from "react";
import ReactDOM from "react-dom";
function App() {
return <h1>hello</h1>;
}
ReactDOM.render(<App />, document.getElementById("root"));
// public -> index.html
<div id="root"></div>;
// webpack.dev.config 中
// 因为我们已经引入react了 且文件为main.js 但是我们的 webpack中的入口文件还是index.js所以我们需要修改入口文件为main.js
entry: './src/main.js',
-
案例说我们可以运行我的项目了
npm run dev
ok 成功报错,
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders -
啥意思?看不懂呗,浏览器看不懂 react 语法,说需要 loader 去处理这些文件,那好我们就安装对应的 loader
## 处理js 文件就是我们耳熟能祥的 babel-loader啦
npm install --save-dev babel-loader @babel/core @babel/preset-react
- 我们安装完成之后,我们需要去配置
loader
, 我们可以去项目中新建.babelrc
文件 写入如下配置
{
"presets": ["@babel/preset-react"],
}
当然我们也可以在 webpack 中配置这些,我们在 webpack.dev.config.js
中添加该配置来处理我们的 js/jsx
文件
{
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-react'],
},
},
},
]
},
}
- 好了,我们现在再次跑一下
npm run dev
,页面已经可以正常展示了 出现了我们的 hello - 那我们的以前的那些 js 函数怎么加载进去呢?哈哈 我们直接在 main.js 中吧我们的 index.js 引入即可,可以看到函数正常执行,紧接着我们就可以写一个小小的
react
组件啦 - 在 src 下我们新建 page 文件夹创建 index.js 文件 写如下代码
import React from "react";
const Page1 = () => {
return (
<div className="page1">
<h1>Page1</h1>
</div>
);
};
export default Page1;
- 我们在 main.js 中引入直接渲染在我们页面中
import React from "react";
import ReactDOM from "react-dom";
import "./index.js";
import Page1 from "./page/index.js";
function App() {
return (
<h1>
<Page1 />
</h1>
);
}
ReactDOM.render(<App />, document.getElementById("root"));
- 可以我们的组件已经回显出来了,我们组件加点样式,我们在 page 下新建 index.css 文件
.page1 {
background-color: red;
}
在 index.js 组件中引入
import React from "react";
import "./index.css";
const Page1 = () => {
return (
<div className="page1">
<h1>Page1</h1>
</div>
);
};
export default Page1;
- 报错啦!和上面的错误类似,index.css 文件浏览理解不了,需要我们一个 loader 处理一下,ok 那就是我们
css loader
style loader
出场啦
npm install style-loader css-loader --save-dev
- 安装完成之后我们又需要在 webpack 中进行配置处理 css 文件(sass scss 同理 安装对应 loader 即可)
{
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-react'],
},
},
},
{
test: /\.css$/,
use: ['style-loader', 'css-loader'],
}
]
},
}
- 我们再次运行
npm run dev
就可以看到我们的样式啦
❓:讲这么就 loader 是什么啊 神神秘秘的?
💡:他就是一个纯函数,可以将我们的资源文件进行处理并通过返回成 Buffer or String
Final loader (./custom_loader/deal_json_loader.js) didn’t return a Buffer or String
- 呐! 我自己写了一个简单的 loader:用户处理 json 数据,比如我们 json 文件的数据是
{
"id": 1,
"name": "张三",
"age": 20,
"sex": "男",
"address": "杭州市余杭区文一西路969号",
"phone": "13800138000",
"email": "13800138000@qq.com",
"birthday": "1990-01-01",
"avatar": "http://www.baidu.com/img/bdlogo.gif",
"tags": ["javascript", "java", "php", "python", "ruby"],
"createTime": "2015-01-01 12:00:00",
"updateTime": "2015-01-01 12:00:00"
}
我想将 json 数据转为接口请求返回的参数格式如:
{
"success": true,
"data": {
"id": 1,
"name": "张三",
"age": 20,
"sex": "男",
"address": "杭州市余杭区文一西路969号",
"phone": "13800138000",
"email": "13800138000@qq.com",
"birthday": "1990-01-01",
"avatar": "http://www.baidu.com/img/bdlogo.gif",
"tags": ["javascript", "java", "php", "python", "ruby"],
"createTime": "2015-01-01 12:00:00",
"updateTime": "2015-01-01 12:00:00"
}
}
- 好,我们直接开始操作,我们新建一个 custom_loader 文件夹,新建
deal_json_loader.js
文件,内容如下
// 自定义loader 将json数据处理为接口模式的数据
module.exports = function (source) {
console.log("deal_json_loader 加载器执行", source);
// 解析 JSON 文件并获取数据
const jsonData = JSON.parse(source);
// 构建输出数据对象
const outputData = {
success: true,
data: jsonData,
};
// 返回处理后的数据作为模块的输出
console.log(outputData, "over-json_loader 加载器endddd");
return JSON.stringify(outputData);
// return outputData
};
就是一个简单的纯入函数,入参就是读取的文件内容,返回的格式就是 Buffer or String
,接下来我们要怎么使用呢?
- 当然是在我们 webpack 中进行配置应用啦!webpack 中添加如下配置:
{
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-react'],
},
},
},
{
test: /\.css$/,
use: ['style-loader', 'css-loader'],
},
{
test: /\.json$/,
use: path.resolve(__dirname, '../custom_loader', 'deal_json_loader.js'),
},
]
},
}
- 添加完成之后,按理说我们就可以正常解析我们项目中的 json 文件了,但是我想将我们 json 文件夹放在我们的项目中最外层,json/*/.json 文件,这样去读取,可是可是!项目打包入口就是 main.js,我试了一下,将最外层的 json 文件引入进去,发现,无法识别这个路径,《我不会了》,换个方式,我将 json 文件夹放在我的 src 目录下正常在 main.js 中引入,并打印出他的数据:
import React from "react";
import ReactDOM from "react-dom";
import "./index.js";
import Page1 from "./page/index.js";
import data from "./index.json";
function App() {
console.log(data, "data");
return (
<h1>
<Page1 />
{JSON.stringify(data)}
</h1>
);
}
ReactDOM.render(<App />, document.getElementById("root"));
data 为我处理好的结果,ok 我们的 loader 就处理完毕啦!
- 后续敬请期待。。。。