tk挠痒痒网址发布页-秘密武器
历史搜索

Webpack详细配置全解析 基础篇

游客2025-05-16 13:11:01
目录文章目录
  1. 概念
  2. 最简单的打包器
  3. 配置文件
  4. loader
  5. 搭建开发环境
  6. plugins
  7. 结语

周末本来是要出去浪的,结果由于疫情的原因,再加上天又这么热,想想还是算了,还是在家里吹空调来的爽,正好项目刚刚结束,趁热打铁,把项目中用到的技术点是时候系统的整理一下,也算是对近期自己的一个自我评价,今天呢就给大家整理一下有关 Webpack 配置的全解析,属于基础篇,主要介绍 webpack 的入口、输出和各种 loader、plugins 的使用以及开发环境的搭建。大佬可以忽略,希望本篇内容对需要的小伙伴有帮助。

概念

官网对 webpack 的定义:

本质上,webpack 是一个现代 JavaScript 应用程序的静态模块打包器(module bundler)。当 webpack 处理应用程序时,它会递归地构建一个依赖关系图(dependency graph),其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个 bundle。

首先 webpack 是一个静态模块打包器,所谓的静态模块,包括脚本、样式表和图片等等;webpack 打包时首先遍历所有的静态资源,根据资源的引用,构建出一个依赖关系图,然后再将模块划分,打包出一个或多个 bundle。再次白 piao 一下官网的图,生动的描述了这个过程:

Webpack详细配置全解析 基础篇 1

vue-loader

最后说一下一个比较特殊的 vue-loader,看名字就知道是用来处理 vue 文件的。

npm i -D vue-loader vue-template-compiler
npm i -S vue

我们首先来创建一个 vue 文件,具体代码在 demo5 中:

//src/App.vue
<template>
    <div id="app">
        <div  @click="tap">{{title}}</div>
    </div>
</template>
<script>
export default {
    name: 'app',
    data(){
        return {
            title: 'app 实例'
        }
    },
    methods: {
        tap(){
            this.title = this.title.split('').reverse().join('')
        }
    }
}
</script>
<style>
#app{
    font-size: 16px;
    background: #ccc;
}
</style>

然后在 webpack 的入口文件中引用它:

//src/main.js
import Vue from 'vue'
import App from './App.vue'

new Vue({
    render: h => h(App)
}).$mount('#app')

不过 vue-loader 和其他 loader 不太一样,除了将它和.vue文件绑定之外,还需要引入它的一个插件:

const VueLoaderPlugin = require('vue-loader/lib/plugin')
module.exports = {
    module: {
        rules: [
        //省略其他 loader
        {
            test: /.vue$/,
            loader: 'vue-loader'
        }]
    },
    plugins: [
        new VueLoaderPlugin(),
    ]
}

这样我们就能愉快的在代码中写 vue 了。

搭建开发环境

在上面的 demo 中我们都是通过命令行打包生成 dist 文件,然后直接打开 html 或者通过 static-server 来查看页面的;但是开发中我们写完代码每次都来打包会严重影响开发的效率,我们期望的是写完代码后立即就能够看到页面的效果;webpack-dev-server 就很好的提供了一个简单的 web 服务器,能够实时重新加载。

首先在我们的项目中安装依赖:

npm i -D webpack webpack-dev-server

webpack-dev-server 的用法和 wepack 一样,只不过他会额外启动一个 express 的服务器。我们在项目中新建一个webpack.dev.config.js配置文件,单独对开发环境进行一个配置,相关代码在 demo6 中:

module.exports = {
    //省略其他配置
    devServer: {
        //启动服务器端口
        port: 9000,
        //默认是 localhost,只能本地访问
        host: "0.0.0.0",
        //自动打开浏览器
        open: false,
        //启用模块热替换
        hot: true,
        //启用 gzip 压缩
        compress: true
    },
    plugins: [
        //热更新插件
        new webpack.HotModuleReplacementPlugin({
        })
    ]
}

通过命令行webpack-dev-server来启动服务器,启动后我们发现根目录并没有生成任何文件,因为 webpack 打包到了内存中,不生成文件的原因在于访问内存中的代码比访问文件中的代码更快。

我们在public/index.html的页面上有时候会引用一些本地的静态文件,直接打开页面的会发现这些静态文件的引用失效了,我们可以修改 server 的工作目录,同时指定多个静态资源的目录:

contentBase: [
  path.join(__dirname, "public"),
  path.join(__dirname, "assets")
]

热更新(Hot Module Replacemen 简称 HMR)是在对代码进行修改并保存之后,webpack 对代码重新打包,并且将新的模块发送到浏览器端,浏览器通过新的模块替换老的模块,这样就能在不刷新浏览器的前提下实现页面的更新。

Webpack详细配置全解析 基础篇 8

plugins

在上面我们也介绍了 DefinePlugin、HtmlWebpackPlugin 等很多插件,我们发现这些插件都能够不同程度的影响着 webpack 的构建过程,下面还有一些常用的插件,plugins 相关代码在 demo7 中。

clean-webpack-plugin

clean-webpack-plugin 用于在打包前清理上一次项目生成的 bundle 文件,它会根据 output.path 自动清理文件夹;这个插件在生产环境用的频率非常高,因为生产环境经常会通过 hash 生成很多 bundle 文件,如果不进行清理的话每次都会生成新的,导致文件夹非常庞大;这个插件安装使用非常方便:

npm i -D clean-webpack-plugin

安装后我们在 config 中配置一下就可以了:

const { CleanWebpackPlugin } = require('clean-webpack-plugin');
module.exports = {
    //其他配置
    plugins: [
        new CleanWebpackPlugin(),
        new HtmlWebpackPlugin({
            template: './public/index.html',
            filename: 'index.html',
        })
    ]
}

mini-css-extract-plugin

我们之前的样式都是通过 style-loader 插入到页面中去,但是生产环境需要单独抽离样式文件,mini-css-extract-plugin 就可以帮我从 js 中剥离样式:

npm i -D mini-css-extract-plugin

我们在开发环境使用 style-loader,生产环境使用 mini-css-extract-plugin:

const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
    //其他配置
    module: {
        rules: [
            {
                test: /.less/,
                use: [{
                    loader: isDev ? 'style-loader' : MiniCssExtractPlugin.loader
                },{
                    loader: 'css-loader'
                },{
                    loader: 'less-loader'
                }]
            }
        ]
    },
    plugins: [
        new MiniCssExtractPlugin({
            filename: "[name].[hash:8].css",
        })
    ]
}

引入 loader 后,我们还需要配置 plugin,提取的 css 同样支持output.filename中的占位符字符串。

optimize-css-assets-webpack-plugin

我们可以发现虽然配置了production模式,打包出来的 js 压缩了,但是打包出来的 css 确没有压缩;在生产环境我们需要对 css 进行一下压缩:

npm i optimize-css-assets-webpack-plugin -D

然后也是引入插件:

const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
module.exports = {
    //其他配置
    plugins: [
        new OptimizeCSSAssetsPlugin(),
    ]
}

copy-webpack-plugin

和 demo6 中一样,我们在 public/index.html 中引入了静态资源,但是打包的时候 webpack 并不会帮我们拷贝到 dist 目录,因此 copy-webpack-plugin 就可以很好地帮我做拷贝的工作了

npm i -D copy-webpack-plugin

在 config 中配置我们需要拷贝的源路径和目标路径:

const CopyWebpackPlugin = require('copy-webpack-plugin');
module.exports = {
    plugins: [
        new CopyWebpackPlugin({
            patterns: [
                {
                    from: 'public/js/*.js',
                    to: path.resolve(__dirname, 'dist', 'js'),
                    flatten: true,
                }
            ]
        }),
    ]
}

ProvidePlugin

ProvidePlugin 可以很快的帮我们加载想要引入的模块,而不用 require。一般我们加载 jQuery 需要先把它 import:

import $ from 'jquery'
$('.box').html('box')

但是我们在 config 中配置 ProvidePlugin 插件后能够不用 import,直接使用$

module.exports = {
    plugins: [
        new webpack.ProvidePlugin({
            $: 'jquery',
            jQuery: 'jquery'
        }),
    ]
}

但是如果在项目中引入了太多模块并且没有 require 会让人摸不着头脑,因此建议加载一些常见的比如 jQuery、vue、lodash 等。

loader 和 plugin 的区别

介绍了这么多 loader 和 plugin,我们来回顾一下他们两者的区别:

loader:由于 webpack 只能识别 js,loader 相当于翻译官的角色,帮助 webpack 对其他类型的资源进行转译的预处理工作。

plugins:plugins 扩展了 webpack 的功能,在 webpack 运行时会广播很多事件,plugin 可以监听这些事件,然后通过 webpack 提供的 API 来改变输出结果。

结语

Webpack 凭借强大的功能,成为最流行和最活跃的打包工具,也是面试时高级程序员必须掌握的“软技能”,所以有必要好好的去系统的学习一下。文章有点长,建议先收藏 CTRL + D 后看,本文是 webpack 基础篇,还有很多生产环境的优化还没有写到;因此各位看官敬请期待优化篇。

本文所有的 demo 代码均在WebpackDemo

推荐阅读:

webpack 系列一之如何写一个自己的 loader

webpack 源码解析二之探究 style-loader 和 css-loader 是如何工作的

webpack 源码解析三之 file-loader 和 url-loader

webpack 源码解析四之 bundle.js 内容分析

webpack 源码解析五之 webpack 处理流程分析

webpack 源码解析六之 HMR 热更新原理

文章参考:公众号【前端壹读】,感兴趣的可以关注一下博主

本文是由用户"游客"发布,所有内容的版权归原作者所有。没有经过书面许可,任何单位或个人不得以任何形式复制、转载、引用本网站的内容。否则将追究法律责任。

相关专题