webpack配置从0到1搭建

491 阅读3分钟

工作中的大多数时候,vue项目或者react项目都是借助脚手架直接搭建项目,这为我们省去了webpack配置的流程,但是也导致我们对webpack不熟悉,而且针对具体的项目,脚手架的配置不一定就是最合适的。因此,无论从实用性还是从学习的角度来看,亲手从0开始配置webpack都是很有必要的。

安装webpack

新建项目文件夹后,npm init初始化后,安装webpack与webpack cli

npm i webpack webpack-cli -D

image.png

搭建

创建基础文件

  1. 新建src目录,里面新建index.js文件,内容如下:
// src/index.js

function test(content) {
 document.querySelector('#app').innerHTML = content;
 }
 test('something')
  1. 与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>
  1. 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",
  },
  1. 执行npm run build,output/main.js中出现打包后的代码

开始配置webpack

基础配置

  1. 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的转化

  1. 创建文件 src/es6.js
// src/es6.js
export default class CountChange {
    count = 1
    increment = () => {
        this.count++
    }
    decrease = () => {
        this.count--;
    }
}
  1. 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的支持

  1. 安装react

npm i react react-dom -S

  1. 安装react相关babel

npm i @babel/preset-react -D

  1. 创建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 />);
  1. 配置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

  1. 下载style-loader css-loader

npm i style-loader css-loader mini-css-extract-plugin -D mini-css-extract-plugin可以把css提取到单独的而文件中

  1. 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']
     }]
   }
 }
  1. 新建一个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可以让我们代码发生变动后,在页面上能立即看见更改,而不用打包

  1. 下载webpack-dev-serve

npm i webpack-dev-server -D

2.增加package.json中的命令

// package.json
"scripts": {
    "start": "webpack serve"
}

重启启动项目 npm run start 至此,一个可以跑react的webpack配置就完成了