webpack相关内容

196 阅读4分钟

一、webpack基本

1、webpack构建流程

初始化流程:从配置文件Shell 语句读取与合并参数,并初始化需要使用的插件和配置插件等执行环境所需要的参数

编译构建流程:从 Entry 出发,针对每个 Module 串行调用对应的 Loader 去翻译文件内容,再找到该 Module 依赖的 Module,递归地进行 Module 编译处理

输出流程:对编译后的Module 组合成 Chunk,把 Chunk 转换成文件,输出到文件系统

2、五大核心概念

webpack 五个核心概念:

  • 入口(Entry): webpack 以哪个文件为入口起点开始打包,分析构建内部依赖图。
  • 输出(Output): webpack 打包后的资源 bundles 输出到哪里去,以及如何命名。
  • Loader(加载器): 让 webpack 能够去处理那些非 JavaScript 文件(webpack 自身只理解 JavaScript)
  • 插件(Plugins):可以用于执行范围更广的任务。插件的范围包括,从打包优化和压缩,一直到重新定义环境中的变量等。
  • 模式(Mode): webpack 使用相应模式的配置。develop模式,production模式,不同的运行环境上线运行。

3、配置及作用

配置属性名
mode默认值为development,值为production时,代码会压缩
entry打包入口,打包成chunk及入口
output打包出口,配置打包位置等信息
plugins插件,可以配置打包过程中所用的插件,如HtmlWebpackPlugin、mini-css-extract-plugin
module模块,配置不同后缀文件打包loader
devServer开发服务,可以配置打开接口proxy等
optimization优化,可以配置抽离公共代码的优化

二、常用依赖及作用

依赖作用
html-webpack-plugin生成html文件,可根据模板生成html文件
webpack-mergewebpack配置合并
mini-css-extract-plugincss处理抽离压缩
style-loadercss处理,但并未抽离,包含在js中
postcss-loader和autoprefixercss浏览器兼容,即在各个css添加前缀
file-loader图片处理,把图片复制一份放到打包目录下
url-loader图片处理,转化为base64
less和less-loaderless处理
webpack-dev-serverwebpack dev打包并启动服务器
cross-env可以设置环境变量,需要放在webpack前使用
webpack-bundle-analyzer打包体积分析
terser-webpack-pluginjs压缩
optimize-css-assets-webpack-plugincss压缩,适用webpack4
css-minimizer-webpack-plugincss压缩,适用webpack5

三、常用插件配置

1、css插件配置

一般需要style-loader、css-loader,

先处理的插件放在后面,因为插件是链式调用从下到上进行

style-loader把css文件放在style标签里面

使用mini-css-extract-plugin抽离css插件优化css文件大小

mini-css-extract-plugin不支持热更新,所以开发环境请使用style-loader

postcss-loader、autoprefixer添加css前缀,进行浏览器兼容

webpack.js配置

    module: {
        rules: [
            {
                test: /.(less|css)$/,
                use: [
                    {
                        loader: MiniCssExtractPlugin.loader
                    },
                    {
                        loader: "css-loader"
                    },
                    {
                        loader: "postcss-loader"
                    },
                    {
                        loader: "less-loader"
                    }
                ]
            }
        ]
    },
    plugins: [
        new MiniCssExtractPlugin({
            filename: "index.css" //输出的css文件名,默认以入口文件名命名(例如main.css)
        })
    ]

postcss.config.js配置

module.exports = {
    plugins: {
        autoprefixer: {
            overrideBrowserslist: [
                "Android 4.1",
                "iOS 7.1",
                "Chrome > 31",
                "ff > 31",
                "ie >= 8"
            ]
        }
    }
};

2、本地图片配置即静态资源配置

一般会用到file-loader,url-loader

file-loader目的是把图片文件复制一份并引用

    module: {
        rules: [
            {
                test: /.(jpg)$/,
                use: [
                    'file-loader'
                ]
            }
        ]
    }

url-loader目的是把图片文件转为base64格式引用,减少http请求次数。一般配置最大文件大小,目的是限制文件大小,文件太大不必转化为base64,否则会导致页面白屏时间增长

图片base64格式优点,减少http请求次数,缺点是太大的情况会影响页面首次加载速度。

    module: {
        rules: [
            {
                test: /.(jpg|webp)$/,
                use: [
                    {
                        loader: "url-loader",
                        options: {
                            limit: 5 * 1024,
                            outputPath: "/path/"
                        }
                    }
                ]
            }

3、html插件

html-webpack-plugin插件的基本作用就是生成html文件。原理很简单:

 将 webpack中entry配置的相关入口chunk 和 extract-text-webpack-plugin抽取的css样式 插入到该插件提供的template或者templateContent配置项指定的内容基础上生成一个html文件, 具体插入方式是将样式link插入到head元素中,script插入到head或者body中。 

 html-webpack-plugin相关配置 

四、其他功能

1、多入口打包

多入口打包

1、在entry中配置入口,即把入口文件打包成chunk,chunk名称就是键名

    entry: {
        index: "./page/index.js",
        main: "./page/main.js"
    },

2、在plugins中添加 new HtmlWebpackPlugin()

    plugins: [
        new HtmlWebpackPlugin({
            template: "./index.html",
            filename: "index.html",
            chunks: ["index"],
            title: "index"
        }),
        new HtmlWebpackPlugin({
            template: "./index.html",
            filename: "main.html",
            chunks: ["main"],
            title: "main"
        })
    ]

2、抽离公共代码

1)抽离js公共模块

抽离公共代码只在生产环境使用,开发环境没有必要

webpack在进行抽离公共代码的时候分为两种,一种是公共模块,一种是第三方模块; 对于公共模块:不需要重复打包,抽离成一个单独的公共模块文件,然后引用即可; 对第三方模块:一般不会轻易改变,所以就单独抽离一个第三方模块的文件,引用即可;

    optimization: {
        splitChunks: {
            chunks: "all",
            cacheGroups: {
                // 第三方模块
                vendors: {
                    name: "vendor", // 每个组的名字
                    priority: 1, // 优先级,越小优先级越高
                    // 检测模块是否来自于node_modules,是否通过npm下载的
                    test: /[\/]node_modules[\/]/,
                    // 设置代码分割的最小界限;
                    // 可以设置成 5 * 1024 大小 5kb
                    // 大于 5kb 的文件才会做分割,也可以设置为 0
                    minSize: 5 * 1024,
                    minChunks: 1 // 检测模块被引用几次就可以单独打包
                },
                // 公共模块
                common: {
                    name: "common",
                    priority: 0,
                    minSize: 0,
                    minChunks: 2
                },
                default: {
                    // 默认设置,可被重写
                    minChunks: 2,
                    priority: -20, // 如果本来已经把代码提取出来,则重用存在的而不是重新产生
                    reuseExistingChunk: true
                }
            }
        }
    }

2)抽离css

使用mini-css-extract-plugin进行css抽离

const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = { 
    module: {
        rules: [
            {
                test: /\.(less)$/,
                use: [
                    MiniCssExtractPlugin.loader,
                    "css-loader",
                    "postcss-loader",
                    "less-loader"
                ]
            }
        ]
    },
    plugins: [
        new MiniCssExtractPlugin({
            filename: "./css/index.css"
        })
    ],
}

3、proxy接口代理配置

module.exports = {
  //...
  devServer: {
    proxy: {
      '/api': {
        target: 'http://localhost:3000',
        pathRewrite: { '^/api': '' },
        changeOrigin: true, // 默认保持主机头,true进行覆盖
        secure: false, // https上运行
      },
    },
  }
};

4、使用NODE_ENV环境变量

需要使用插件cross-env,eg:

"dev": "cross-env NODE_ENV=development webpack-dev-server --config ./build/webpack.dev.config.js"
console.log(process.env.NODE_ENV);

5、代码压缩

1)js代码压缩

可以使用terser-webpack-plugin进行压缩,实际上配置 mode: "production"本事就带有js压缩功能,但是terser-webpack-plugin也可以配置其他内容比如去除console.log

2)css代码压缩

optimize-css-assets-webpack-plugin可以压缩webpack4的css

css-minimizer-webpack-plugin可以用来压缩webpack5的css

const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin");
......
    optimization: {
        minimizer: [new OptimizeCSSAssetsPlugin({})],
        }
......

6、打包体积分析

使用webpack-bundle-analyzer进行打包分析

const { BundleAnalyzerPlugin } = require("webpack-bundle-analyzer");
...
    plugins: [
        new BundleAnalyzerPlugin(),
    ]
...

五、参考

webpack优化

面试官:说说webpack的构建流程?