webpack基础

206 阅读6分钟

webpack基础

文档

  • 官方网站::https://webpack.js.org/

1.webpack简介

web原理
web原理

概念:
webpack is a module bundler(模块打包⼯具)

Webpack是⼀个打包模块化JavaScript的⼯具,它会从⼊⼝模块出发,识别出源码中的模块化导⼊语句,递 归地找出⼊⼝⽂件的所有依赖,将⼊⼝和其所有的依赖打包到⼀个单独的⽂件中,是⼯程化、⾃动化思想在前端开发中的体现。

2.安装webpack

2.1-环境准备

nodejs:https://nodejs.org/en

版本参考官⽹发布的最新版本,可以提升webpack的打包速度,建议安装最新的稳定版

2.2-全局安装 不推荐

1# 安装webpack V4+版本时,需要额外安装webpack-cli
2npm install webpack webpack-cli -g
3
4# 检查版本
5webpack -v
6
7# 卸载
8npm uninstall webpack webpack-cli -g

tip:全局安装webpack,这会将你项⽬中的webpack锁定到指定版本,造成不同的项⽬中因为webpack依赖不同版 本⽽导致冲突,构建失败

2.3-项目安装 推荐

 1# 安装最新的稳定版本
2npm i -D webpack
3
4# 安装指定版本
5npm i -D webpack@<version>
6
7# 安装最新的体验版本 可能包含bug,不要⽤于⽣产环境
8npm i -D webpack@beta
9
10# 安装webpack V4+版本时,需要额外安装webpack-cli
11npm i -D webpack-cli

2.4-检查安装

1webpack -v //command not found 默认在全局环境中查找
2
3npx webpack -v// npx帮助我们在项⽬中的node_modules⾥查找webpack
4
5./node_modules/.bin/webpack -v//到当前的node_modules模块⾥指定webpack

3.启动webpack执行构建

3.1- webpack默认配置

  • webpack默认⽀持JS模块和JSON模块
  • ⽀持CommonJS Es moudule AMD等模块类型
  • webpack4⽀持零配置使⽤,但是很弱,稍微复杂些的场景都需要额外扩展

3.2- 准备执行构建

  • 新建src文件夹
  • 新建src/index.js
1//src/index.js
2console.log('hello webpack')
3
4// 执行构建
5npx webpack

3.4-构建成功

我们会发现⽬录下多出⼀个 dist ⽬录,⾥⾯有个 main.js ,这个⽂件是⼀个可执⾏的JavaScript⽂ 件,⾥⾯包含webpackBootstrap启动函数。

3.5-默认配置

 1const path = require("path");
2module.exports = {
3 // 必填 webpack执⾏构建⼊⼝
4 entry: "./src/index.js",
5 output: {
6 // 将所有依赖的模块合并输出到main.js
7 filename: "main.js",
8 // 输出⽂件的存放路径,必须是绝对路径
9 path: path.resolve(__dirname, "./dist")
10 }
11};

4.webpack核心配置概念

零配置是很弱的,特定的需求,总是需要⾃⼰进⾏配置

webpack有默认的配置⽂件,叫 webpack.config.js ,我们可以对这个⽂件进⾏修改,进⾏个性化配置

webpack.config.js配置基础结构
 1//webpack配置文件
2module.exports = {
3 entry: "./src/index.js", //打包⼊⼝⽂件
4 output: "./dist", //输出结构
5 mode: "production", //打包环境
6 module: {
7     rules: [
8     //loader模块处理
9         {
10             test: /\.css$/,
11             use: "style-loader"
12         }
13     ]
14 },
15 plugins: [new HtmlWebpackPlugin()] //插件配置
16};

4.1 - entry:入口文件

执行构建的入口文件 支持字符串,数组,对象

 1//单⼊口 SPA,本质是个字符串
 2entry:{
 3 main'./src/index.js'
 4}
 5==相当于简写===
 6entry:"./src/index.js"
 7
 8//多⼊⼝ MPA entry是个对象
 9entry: {
10    index: './src/index.js',
11    list: './src/list.js',
12    detail: './src/detail.js',
13},

4.2 - output:打包文件的输出路径

执行构建后的资源名称和位置等信息

1 output: {
2     // 必须为绝对路径,执行构建后的资源存放位置
3     path: path.resolve(__dirname, './build'),
4     // 只有一个输出文件
5     // filename: "mian.js",//输出⽂件的名称
6     //    如果是多个出口文件
7     // 执行构建后的资源名称 []占位符,name会根据key值来指定file的名称
8     filename: '[name].js',
9},

4.3 - mode :代码打包的环境

Mode⽤来指定当前的构建环境

  • production -- 生产环境 代码会尽量压缩以达到最小体积
  • development --开发环境 代码具有可读性且带有注释
  • none -- 默认
选项 描述
development 会将 DefinePluginprocess.env.NODE_ENV 的值设置为 development . 启用 NamedChunksPluginNamedModulesPlugin
production 会将 DefinePluginprocess.env.NODE_ENV 的值设置为 production . 启用 FlagDependencyUsagePlugin , FlagIncludedChunksPlugin , ModuleConcatenationPlugin , NoEmitOnErrorsPlugin , OccurrenceOrderPlugin , SideEffectsFlagPluginTerserPlugin
none 不使用任何默认优化选项

如果没有设置,webpack 会给 mode 的默认值设置为 production

请注意,设置 NODE_ENV 并不会自动地设置 mode

开发阶段的开启会有利于热更新的处理,识别哪个模块变化

⽣产阶段的开启会有帮助模块压缩,处理副作⽤等⼀些功能

4.4 - module:模块

模块,在 Webpack ⾥⼀切皆模块,⼀个模块对应着⼀个⽂件。

Webpack 会从配置的 Entry 开始递归找 出所有依赖的模块。

当webpack处理到不认识的模块时,需要在webpack中的module处进⾏配置,当检测到是什么格式的 模块,使⽤什么loader来处理。

 1module:{
 2 rules:[
 3     {
 4         test:/\.xxx$/,//指定匹配规则
 5         use:{
 6             loader: 'xxx-load'//指定使⽤的loader
 7         }
 8      }
 9 ]
10}

loader: file-loader:处理静态资源模块

原理是把打包⼊⼝中识别出的资源模块,移动到输出⽬录,并且返回⼀个地址名称

所以我们什么时候⽤file-loader呢?

场景:就是当我们需要模块,仅仅是从源代码挪移到打包⽬录,就可以使⽤file-loader来处理, txt,svg,csv,excel,图⽚资源啦等等

1npm install file-loader -D //安装

小栗子:处理各种图片格式

 1//webpack.config.js
 2module: {
 3     rules: [
 4         {
 5             test/\.(png|jpe?g|gif)$/,
 6             //use使⽤⼀个loader可以⽤对象,字符串,两个loader需要⽤数组
 7             use: {
 8                 loader"file-loader",
 9                 // options额外的配置,⽐如资源名称
10                 options: {
11                 // placeholder 占位符 [name]旧资源模块的名称
12                 // [ext]旧资源模块的后缀
13                 // https://webpack.js.org/loaders/file-loader#placeholders
14                 name"[name]_[hash].[ext]",
15                 //打包后的存放位置
16                 outputPath"images/"
17                 }
18             }
19         }
20     ]
21 },
1import pic from "./logo.png";
2var img = new Image();
3img.src = pic;
4img.classList.add("logo");
5var root = document.getElementById("root");
6root.append(img);

样式处理:

Css-loader 分析css模块之间的关系,并合成⼀个css

Style-loader 会把css-loader⽣成的内容,以style挂载到⻚⾯的heade部分

多个loader需要使用数组连接

1npm install style-loader css-loader -D //安装
 1// 基本配置css-loader
 2{
 3     test/\.css$/,
 4     use: ["style-loader""css-loader"]
 5}
 6// 使用options配置
 7{
 8     test:/\.css$/,
 9     use:[{
10         loader:"style-loader",
11         options: {
12             injectType"singletonStyleTag" // 将所有的style标签合并成⼀个
13         }
14     },"css-loader"]
15}

4.5 - bundle:打包构建的文件

概念:由多个不同的模块生成,bundle包含了加载和编译过后的最终源文件版本。

bundle分离(Bundle Splitting):优化构建的方法。允许webpack为应用程序生成多个bundle。当其他某些bundle改动时,彼此独立的另一些bundle不受影响。减少需要重新发布的代码量。

bundle
bundle

4.6 - chunk

概念:和entry有关,入口文件与依赖模块组合,经过webpack构建,会生成一段代码,叫做chunk

chunk
chunk

4.7 - loader:加载器

概念:

模块解析,模块转换器,⽤于把模块原内容按照需求转换成新内容。

webpack是模块打包⼯具,⽽模块不仅仅是js,还可以是css,图⽚或者其他格式,但是webpack默认只知道如何处理js和JSON模块,那么其他格式的模块处理,和处理⽅式就需要 loader了

loader 让 webpack 能够去处理其他类型的文件,并将它们转换为有效 模块,以供应用程序使用,以及被添加到依赖图中。

loader的配置参数

  1. test 属性,识别出哪些文件会被转换。

  2. use 属性,定义出在进行转换时,应该使用哪个 loader。

    webpack.config.js

 1 module:{
 2        // 打包规则 告诉webpack遇到何种类型的文件,语法应该怎么处理
 3        rules:[
 4            {
 5                test:/\.css$/,
 6                // css-loader作用非常的专一 ,把css in js的方式放在bundle文件中
 7                // loader是有执行顺序的,从右到左
 8                use:['style-loader','css-loader'],
 9            },
10
11        ]
12
13    },

以上配置中,对一个单独的 module 对象定义了 rules 属性,里面包含两个必须属性:testuse。这告诉 webpack 编译器(compiler) 如下信息

“嘿,webpack 编译器,当你碰到「在 require()/import 语句中被解析为 '.css' 的路径」时,在你对它打包之前,先 use(使用) css-loader 转换一下。并且再用style-loader呈现在浏览器中”

常⻅的loader

style-loader // 将样式添加到style标签插入头部

css-loader //允许将css文件通过require的方式引入,并返回css代码

less-loader //处理less文件

sass-loader //处理sass文件

postcss-loader // 处理css浏览器兼容性

ts-loader //将Ts转换成js

babel-loader//转换ES6、7等js新特性语法

file-loader //分发文件到output目录并返回相对路径

html-minify-loader //压缩HTML

eslint-loader

loader特性

  • loader 处理webpack不⽀持的格式⽂件,模块

  • ⼀个loader只处理⼀件事情

  • loader 从右到左地取值(evaluate)/执行(execute)

  • loader 支持链式传递,链中的每个 loader 会将转换应用在已处理过的资源上

  • loader 可以是同步的,也可以是异步的

  • loader 运行在 Node.js 中,并且能够执行任何 Node.js 能做到的操作

  • loader 中use可以通过loader字段和 options 对象配置

 1//例子 以下使用loader字段指定为file-loader 并且配置了options对象
 2{
 3    test: /\.(png|jpe?g|gif|svg)$/,
 4    use: {
 5        loader: "file-loader",
 6        options: {
 7            name: "[name].[ext]",
 8            outputPath: "images/",
 9        },
10    },
11},

4.8 - Plugins: 插件

  • 作⽤于webpack打包整个过程
  • webpack的打包过程是有(⽣命周期概念)钩⼦
  • webpack.config.js中配置plugins,plugins是一个数组

plugin 可以在webpack运⾏到某个阶段的时候,帮你做⼀些事情,类似于⽣命周期的概念扩展插件,在 Webpack 构建流程中的特定时机注⼊扩展逻辑来改变构建结果或做你想要的事情。 作⽤于整个构建过程

HtmlWebpackPlugin

作用:htmlwebpackplugin会在打包结束后,⾃动⽣成⼀个html⽂件,并把打包⽣成的js模块引⼊到该html 中。

1npm install --save-dev html-webpack-plugin // 安装

配置

 1title: ⽤来⽣成⻚⾯的 title 元素
 2filename: 输出的 HTML ⽂件名,默认是 index.html, 也可以直接配置带有⼦⽬录。
 3template: 模板⽂件路径,⽀持加载器,⽐如 html!./index.html
 4inject: true | 'head' | 'body' | false ,注⼊所有的资源到特定的 template 或者
 5templateContent 中,如果设置为 true 或者 body,所有的 javascript 资源将被放置到 body
 6元素的底部,'head' 将放置到 head 元素中。
 7favicon: 添加特定的 favicon 路径到输出的 HTML ⽂件中。
 8minify: {} | false , 传递 html-minifier 选项给 minify 输出
 9hash: true | false, 如果为 true, 将添加⼀个唯⼀的 webpack 编译 hash 到所有包含的脚本和
10CSS ⽂件,对于解除 cache 很有⽤。
11cache: true | false,如果为 true, 这是默认值,仅仅在⽂件修改之后才会发布⽂件。
12showErrors: true | false, 如果为 true, 这是默认值,错误信息会写⼊到 HTML ⻚⾯中
13chunks: 允许只添加某些块 (⽐如,仅仅 unit test 块)
14chunksSortMode: 允许控制块在添加到⻚⾯之前的排序⽅式,⽀持的值:'none' | 'manual' |
15'auto'
16excludeChunks: 允许跳过某些块,(⽐如,跳过单元测试的块)

基础小栗子:

 1// webpack.config.js
 2const path = require("path");
 3const htmlWebpackPlugin = require("html-webpack-plugin");
 4module.exports = {
 5     ...
 6     plugins: [
 7         new htmlWebpackPlugin({
 8             title: "My App",
 9             filename: "app.html",
10             template: "./src/index.html"
11         })
12     ]
13
14 //index.html
15 <!DOCTYPE html>
16<html lang="en">
17 <head>
18     <meta charset="UTF-8" />
19     <meta name="viewport" content="width=device-width, initial-scale=1.0" />
20     <meta http-equiv="X-UA-Compatible" content="ie=edge" />
21     <title><%= htmlWebpackPlugin.options.title %></title>
22 </head>
23 <body>
24     <div id="root"></div>
25 </body>
26</html>

chunksSortMode字段,可以帮助我们定义chunk文件顺序

 1//假如多个html模板有多个引入文件
 2 plugins: [
 3        new htmlWebpackPlugin({
 4          template: "./src/index.html",
 5          filename: "index.html",
 6          chunks: ["index", "list"],
 7        }),
 8        new htmlWebpackPlugin({
 9          template: "./src/index.html",
10          filename: "list.html",
11          chunks: ["list", "detail"],
12        }),
13        new htmlWebpackPlugin({
14          template: "./src/index.html",
15          filename: "detail.html",
16          chunks: ["detail","index","list"],
17          chunksSortMode:'manual',
18        }),
19      ],
20   //detail.html
21   <!DOCTYPE html>
22<html lang="en">
23  <head>
24    <meta charset="UTF-8" />
25    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
26    <title>Document</title>
27  </head>
28  <body>
29    <div id="app"></div>
30      <script src="detail.js"></script>
31      <script src="index.js"></script>
32      <script src="list.js"></script>
33  </body>
34</html>

我们设置chunksSortMode为'manual'的话,引入打包的js文件顺序就是按照chunks数组的顺序,十分方便

MiniCssExtractPlugin

作用:该插件将CSS提取到单独的文件中。它为每个包含CSS的JS文件创建一个CSS文件。它支持CSS和SourceMap的按需加载。

1npm install --save-dev mini-css-extract-plugin // 安装

小栗子

 1plugins: [
 2    new MiniCssExtractPlugin({
 3      filename: '[name].[contenthash].css',
 4      chunkFilename: '[name].[contenthash].css',
 5    })
 6  ],
 7  module: {
 8    rules: [
 9      {
10        test: /\.css$/,
11        use: [MiniCssExtractPlugin.loader, 'css-loader']
12      }
13    ]
14  }

tip:该插件要搭配MiniCssExtractPlugin.loader使用

?盘一盘bundle chunk entry module

  • bundle 就是打包出来的资源文件
  • chunk 是资源文件里面的代码块
  • bundle是资源文件本身,chunk是文件里面的代码片段 一个bundle 对应一个 chunk
  • bundle里面包含了chunk
  • entry 是入口文件
  • module 是entry里面依赖(引入)的模块
  • entry里面可以有module也可以没有module 有引入就有module

总结

下面是我个人整理的一张思维导图做为学习记录

webpack基础
webpack基础