工作中的大多数时候,vue项目或者react项目都是借助脚手架直接搭建项目,这为我们省去了webpack配置的流程,但是也导致我们对webpack不熟悉,而且针对具体的项目,脚手架的配置不一定就是最合适的。因此,无论从实用性还是从学习的角度来看,亲手从0开始配置webpack都是很有必要的。
安装webpack
新建项目文件夹后,npm init初始化后,安装webpack与webpack cli
npm i webpack webpack-cli -D
搭建
创建基础文件
- 新建src目录,里面新建index.js文件,内容如下:
// src/index.js
function test(content) {
document.querySelector('#app').innerHTML = content;
}
test('something')
- 与src同级新建index.html文件
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>webpack</title>
</head>
<body>
<div id="app"></div>
</body>
</html>
<!--output/main.js是下面将要配置的打包后的文件路径 -->
<script type="text/javascript" src="./output/main.js"></script>
- package.json文件中添加打包命令 其中./src/index.js是入口文件, -o指的是输出目录,./output是输出目录, --mode=development指的是开发环境, --devtool=cheap-module-source-map指的是会保留打包后代码与源代码的映射关系,方便调试。
后续这些配置都会放在webpack.config.js中
// package.json
"scripts": {
"build": "webpack ./src/index.js -o ./output --mode=development --devtool=cheap-module-source-map",
},
- 执行npm run build,output/main.js中出现打包后的代码
开始配置webpack
基础配置
- src同级新建webpack.config.js文件,将刚刚build后面跟的那些参数都转移到配置文件中
// package.json
"scripts": {
"build": "webpack"
},
// webpack.config.js
const path = require('path');
module.exports = {
mode: 'development',
devtool: 'cheap-module-source-map',
entry: './src/index.js',
output: {
path: path.resolve(__dirname, 'output'),
filename: 'main.js',
},
}
增加ES6的转化
- 创建文件 src/es6.js
// src/es6.js
export default class CountChange {
count = 1
increment = () => {
this.count++
}
decrease = () => {
this.count--;
}
}
- src/index.js中引入es6.js文件
// src/index.js
import CountChange from './es6';
const instance = new CountChange();
function test(content) {
document.querySelector('#app').innerHTML = content;
}
test(instance.count)
这时候执行打包命令,可以看见打包后的文件里,并没有把class转化为function,那么我们需要配置babel来转化一下
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": () => (/* binding */ CountChange)
/* harmony export */ });
class CountChange {
count = 1
increment = () => {
this.count++
}
decrease = () => {
this.count--;
}
}
...
(() => {
/*!**********************!*\!*** ./src/index.js ***! \**********************/
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _es6__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*!./es6 */ "./src/es6.js");
安装babel
npm i @babel/core @babel/preset-env babel-loader -D
babel/preset-env是babel预设的,可以让我们使用比较新的javaScript语法
webpack.config.js中增加babel配置
// webpack.config.js
...
module: {
rules: [{
test: /\.js$/,
use: {
loader: 'babel-loader',
options: {
presets: [
'@babel/preset-env'
],
}
}
}]
}
}
此时再执行打包命令,output/main.js中class已经被转化为 new function
增加对react的支持
- 安装react
npm i react react-dom -S
- 安装react相关babel
npm i @babel/preset-react -D
- 创建src/react.js
// src/react.js
import React from 'react';
import { createRoot } from 'react-dom/client'
const App = () => <div>App</div>;
createRoot(document.getElementById('app'))
.render(<App />);
- 配置webpack.config.js 要把入口文件改为react.js,同时加上@babel/preset-react
// webpack.config.js
{
entry: './src/react.js', // 修改⽂件⼊⼝
module: {
rules: [{
test: /\.js$/,
use: {
loader: 'babel-loader',
options: {
presets: [
'@babel/preset-env', '@babel/preset-react'
],
}
}
}]
}
}
打包之后,访问index.js也是成功的
webpack优化,chunks的抽离
webpack.config.js中新增optimization字段
// webpack.config.js
{
optimization: {
splitChunks: {
cacheGroups: {
vendor: {
filename: 'vendor.js',
chunks: 'all',
test: /[\\/]node_modules[\\/](react|react-dom)[\\/]/
},
}
}
}
}
这时候再执行打包命令,会额外打包出一个vendor.js,这是根据配置的规则,把react和react-dom的代码抽离出来,减小了main.js的体积
添加css loader
- 下载style-loader css-loader
npm i style-loader css-loader mini-css-extract-plugin -D mini-css-extract-plugin可以把css提取到单独的而文件中
- webpack.config.js中添加配置
// webpage.config.js
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
...
plugins: [
new MiniCssExtractPlugin({
filename: "[name].css",
chunkFilename: "[id].css"
})
],
module: {
rules: [
...,
{
test: /\.css$/,
use: [MiniCssExtractPlugin.loader, 'css-loader']
}]
}
}
- 新建一个css文件,然后引入到react.js中 再打包出来的output目录下会多一个main.css文件,需要手动引入到我们的index.html文件中才能生效
引入html-webpack-plugin插件
html-webpack-plugin插件能在打包的时候生产一个html文件,并且自动把生产的js,css文件引入, 同时我们可以提供一份模块文件,作为生成html的模板
npm i html-webpack-plugin -D
// webpack.config.js
const HtmlWebpackPlugin = require('html-webpack-plugin');
{
...
plugins:[
...
new HtmlWebpackPlugin(
{
template: './index.html'
})
],
}
添加热更新HRM
一直到现在,我们项目发生了变动之后,还都是通过手动重新打包的方式,然后才能在页面上看见更改,webpack-dev-serve可以让我们代码发生变动后,在页面上能立即看见更改,而不用打包
- 下载webpack-dev-serve
npm i webpack-dev-server -D
2.增加package.json中的命令
// package.json
"scripts": {
"start": "webpack serve"
}
重启启动项目 npm run start 至此,一个可以跑react的webpack配置就完成了