Webpack笔记 | 青训营笔记

186 阅读4分钟

这是我参与「第四届青训营 」笔记创作活动的第5天。

Webpack简介

webpack本质上是一种前端资源编译、打包工具,支持以下特性

  • 多份资源文件打包成一个Bundle
  • 支持Babel、Eslint、Ts、CoffeScript、Less、Sass
  • 支持模块化处理css、图片等资源文件
  • 支持HMR + 开发服务器
  • 支持持续监听、持续构建
  • 支持代码分离
  • 支持Tree-shaking
  • 支持Sourcemap
  • ···

初始准备

安装

npm install webpack webpack-cli —save-dev

运行

npx webpack

自定义webpack配置 entry:入口文件 output:输出文件 mode:development/production 开发环境需求

  • 模块热更新(开启本地服务,实时更新)
  • sourcemap(方便打包调试)
  • 接口代理(配置proxyTable解决开发环境跨域问题)
  • eslint(代码规范检查) 生产环境需求
  • 提取公共代码
  • 压缩混淆
  • 文件压缩/base64编码
  • 去除无用代码

使用Webpack

关于webpack的使用方法,基本都围绕“配置”展开,大致可以分为两类

  • 流程类:作用于流程中某个或多个环节,直接影响打包效果的配置项
  • 工具类:主流程之外,提供更多工程化能力的配置项

配置总览

使用频率

  • entry/output
  • module/plugins
  • mode
  • watch/devServer/devtool

Loader

什么是loader webpack自身只支持js和json这两种格式的文件,对于其他文件需要通过loader将其转换为commonJS规范的文件后,webpack才能解析到,常见loader如下

加载CSS

{
	test: /\.css/,
	use: ['css-loader', 'style-loader']
}

抽离和压缩CSS

const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin')

mode: 'production',
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin')

mode: 'production',

plugins: [
	new MiniCssExtractPlugin({ filename: 'styles/[contenthash].css' })
],

module: {
	rules: [
		{
        test: /\.(css|less)$/,
        use: [MiniCssExtractPlugin.loader, 'css-loader', 'less-loader']
    },
	]
},

optimization: {
  minimizer: [new CssMinimizerPlugin()]
}

加载images图像

{
  test: /\.(jpg|png)$/,
  use: {
    loader: "url-loader",
    options: {
      limit: 25000, //25KB以上图像会调用file-loader
    },
  },
},
{
  test: /\.(jpg|png)$/,
  use: {
    loader: "file-loader",
    options: {
      name: "[path][name].[hash].[ext]",
    },
  },
},

加载数据

{
	test: /\.(csv|tsv)$/,
	use: 'csv-loader'
},
{
	test: /\.xml$/
	use: 'xml-loader'
}

自定义JSON模块parser

{
	test: /\.tmol$/,
	type: 'json',
	parser: {
		parser: toml.parse
	}
},

{
	test: /\.yaml$/,
	type: 'json',
	parser: {
		parser: yaml.parse
	}
},

{
	test: /\.json5$/,
	type: 'json',
	parser: {
		parser: json5.parse
}

Babel-loader

对不支持es6的浏览器使用babel-loader打包将es6转化为es5

{
	test: /\.js/,
	exclude: /node_modules/,
	use: {
		loader: 'babel-loader',
		options: {
			preset: ['@babel/preset-env']
		}
	}
}

插件

Plugin 是一个扩展器,它丰富了 webpack 本身,针对是 loader 结束后,webpack 打包的整个过程,它并不直接操作文件,而是基于事件机制工作,会监听 webpack 打包过程中的某些节点,执行广泛的任务。

插件的特点

  • 是一个独立的模块
  • 模块对外暴露一个 js 函数
  • 函数的原型 (prototype) 上定义了一个注入 compiler 对象的 apply方法 apply 函数中需要有通过 compiler 对象挂载的 webpack 事件钩子,钩子的回调中能拿到当前编译的 compilation 对象,如果是异步编译插件的话可以拿到回调 callback
  • 完成自定义子编译流程并处理 complition 对象的内部数据
  • 如果异步编译插件的话,数据处理完成后执行 callback 回调。

热更新插件

模块热更新插件。Hot-Module-Replacement 的热更新是依赖于 webpack-dev-server,后者是在打包文件改变时更新打包文件或者 reload 刷新整个页面,HRM 是只更新修改的部分。

const webpack = require('webpack')

plugins: [
  new webpack.HotModuleReplacementPlugin(), // 热更新插件
]

html-webpack-plugin

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

const HtmlWebpackPlugin = require('html-webpack-plugin')

plugins: [
  new HtmlWebpackPlugin({
    filename: 'index.html',
    template: path.join(__dirname, '/index.html'),
    minify: {
      // 压缩HTML文件
      removeComments: true, // 移除HTML中的注释
      collapseWhitespace: true, // 删除空白符与换行符
      minifyCSS: true, // 压缩内联css
    },
    inject: true,
  }),
]

clean-webpack-plugin

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

const { CleanWebpackPlugin } = require('clean-webpack-plugin')

plugins: [
  new HtmlWebpackPlugin({
    template: path.join(__dirname, '/index.html'),
  }),
  new CleanWebpackPlugin(), // 所要清理的文件夹名称
]

开发环境配置

  1. 使用source map devtool: 'inline-source-map‘ 在浏览器中可以定位到具体的错误位置
  2. 使用watch mode npx webpack -watch 如果文件被更新,代码将被重新编译,不必手动运行整个构建
  3. 使用webpack-dev-server 提供了一个基本的web server,并且具有live reloading功能