webpack 入门笔记

433 阅读14分钟

作为一个webpack小白的我,最近也开始学习了,但是苦于不知道怎么学,最近看了一些讲解webpack的视频还是觉得挺不错的,最起码对于刚入门的我来说还是觉得学到了不少,下面是最近看视频和文章学习到的一些内容,有问题请多指教哦。

1. webpack作用

webpack的核心功能

打包。

什么是打包

简而言之打包就是将多个文件合并到一个js文件中,也就是说开发完成后合并的过程就是打包。

为什么使用webpack

我们在开发时在html页面都是通过手动引入我们需要的多个文件,如果打包成一个文件,会减少http请求数,能让我们的页面更快的加载和显示。而且webpack还有很多其他的功能,例如开启本地服务器,边写代码边更新,压缩等功能。总之就是给我们带来了很多便利的功能。

2.webpack的常用术语解释

Module

模块,分割的代码单元,webpack 中的模块可以是JS,CSS,LESS,TS,JSX等静态文件,可以说我们手写的一个个的文件都是module,他们是webpack处理文件的单位。

bundle

bundle (输出束),许多不同的模块生成,可以理解成最终的输出文件。

chunk

chunk就是webpack根据文件中的引用关系生成chunk文件。

大概可以理解为:我们手写的文件是module,webpack针对文件中引用处理后的文件是chunk,最终生成的输出文件是bundle。

3 webpack的5个核心概念

入口(entry)

Entry(入口),指示 webpack 应该使用哪个模块(module)作为入口开始打包,并且建立其内部依赖图。入口可以是单入口也可以是多入口。

输出(output)

output指示多个文件合并成一个文件(bundle)以后在哪里输出,怎么命名。

loader

webpack 只能理解 JavaScript 和 JSON 文件,这是 webpack 开箱可用的自带能力。loader 让 webpack 能够去处理其他类型的文件,并将它们转换为有效 模块,以供应用程序使用,以及被添加到依赖图中。

loader的使用步骤是1.下载,2.使用

插件(plugin)

plugin用于转换某些类型的模块,而插件则可以用于执行范围更广的任务。包括:打包优化,资源管理,注入环境变量。

plugin的使用步骤是1.下载,2.引入,3.使用

模式(mode)

mode有development(开发模式),production(生产模式),分别提供开发者调试的环境和代码优化上线的环境。

4 webpack初始化

1. 生成package.json

首先创建文件夹webpack-demo文件夹,在webpack-demo目录下执行npm init -y ,生成package.json配置文件

image.png

2. 安装webpack webpack-cli

执行npm install webpack webpack-cli --save-dev,执行成功后生成了node-modules文件夹

注:命令行中-g -D -S的区别

-g --global的简写,对模块进行全局安装,-g安装的模块是这台电脑的项目都能用 -D --save-dev 对模块进行局部安装,局部的意思是只针对当前项目,是开发环境用到,生产环境用不到,模块写入到package.json的devDependencies 对象中。

devDependencies对象,是我们开发的时候需要用到的一些包,只用于开发阶段,真正打包上线的时候并不需要这些包,因为这些工具只是你用来打包代码的,是用来识别特定文件以及代码,帮助我们生产最终文件的。

模块安装到项目文件夹下的node_modules文件夹下

-S --save的简写,对模块进行全局安装,不止用于开发环境,也用于生产环境,模块写入到package.json的dependencies 对象中。

dependencies对象,这个与devDependencies不同,是需要发布到生产环境中的,就比如你要跑一个基于vue的项目,所以需要vue.js来支持,vue.js文件就需要跟随项目到最终的生产环境。npm i vue -S即可将Vue模块安装到项目的依赖中,并一同发布到生产环境。

模块安装到项目文件夹下的node_modules文件夹下

3. 创建配置文件

在根目录下创建webpack.config.js

使用该配置文件时执行webpack 命令即可执行打包,但是有个疑问就是配置文件一定要是这个吗,其实不是的,例如我想要使用xxx.js作为配置文件呢?我们可以通过运行命令webpack --config xxx.js来指定配置文件。

5 webpack开发环境配置

开发环境配置需要设置配置文件 mode:'development'

1. 打包css

我们知道webpack只能理解js和json文件,无法直接对css打包,这个时候就需要借助css-loader,css-loader是用来解析css,把css加载到js中。

  • 编写文件

image.png

image.png

  • 安装css-loader npm i css-laoder -D
  • 配置css-loader

image.png

  • 结果 可以看到index.css已经被引入

image.png

2. 打包less

首先less.css要被less-loader加载,转化为css,然后再被css-loader加载到js中

  • 编写文件

image.png

image.png

  • 安装 less less-loader css-loader less-loader安装时需要同时安装less npm i less-loader less css-loader -D
  • 配置less-loader css-loader

image.png

  • 结果 执行了webpack后报错了,报错内容如下

image.png 原因是less-loader安装的版本过高 解决办法是:1.npm uninstall less-loader 2.npm install less-loader@5.0.0

image.png less打包成功。

3. 打包html

打包html需要用到html-webpack-plugin,默认会创建一个空的 HTML,自动引入打包输出的所有资源(JS/CSS),我们也可以自己创建html文件,不需要再html引入文件,使用这个插件后会自动引入

  • 编写文件

image.png

image.png

image.png

  • 下载plugin包 npm install --save-dev html-webpack-plugin
  • 配置文件

image.png

  • 结果 执行结果出错,还是因为html-webpack-plugin版本过高,解决办法1.npm uninstall html-webpack-plugin,2.npm install i html-webpack-plugin@4.4.1 -D

image.png 最终结果

image.png

image.png

4. 展示css效果

通过以上步骤mian.js已经被引入到html,但是实际上css并没有生效,也就是说html的样式并没有被改变,因为css其实并没有被应用到html中,这个时候就需要用到style-loader了。style-loader的作用是将css-loader解析的内容挂载到style标签下,并且将style标签加入到html文档中。

  • 编写文件 同上
  • 下载style-loader npm i style-loader -D
  • 配置文件

image.png

  • 结果

image.png

image.png 可以看到样式已生效。

4. 打包图片资源

图片资源可以在样式中引用,比如说背景图片,也可以直接在html中使用,file-loader或者是url-loader都是可以处理图片资源的,他们的区别就是url-loader可以设置在图片大小低于某个阈值的时候base64处理,这样可以减少请求,但是他们默认都不能处理html中的图片,html中的图片可以通过html-loader引入,从而能被url-loader进行处理。 -编写文件

image.png

image.png

image.png

  • 下载url-loader或者file-loader以及html-loader
  • npm install --save-dev html-loader url-loader file-loader
  • 配置文件

image.png

结果 不出意料,又报错了,还是下载版本过高的原因,1.npm uninstall html-loader url-loader file-loader,2.npm install html-loader@0.5.5 url-loader@3.0.0 file-loader@5.0.2 -D

image.png image.png

5. 打包其他资源

  • 引入其他文件 image.png
  • 配置文件

image.png -结果

image.png

6. devServer

devServer只在开发环境中生效,如果需要derServe中的配置生效,需要执行webpack-dev-server命令,并且如果修改了其中的配置需要重新执行命令。

  • devServer.open 在DevServer第一次构建完成时,自动用浏览器打开网页,默认是true
  • devServer.hot 启动 webpack 的模块热替换,在修改源代码后能实时的在浏览器看到更新后的效果
  • devServer.compress 为每个静态文件开启 gzip压缩
  • devServer.contentBase 项目构建后路径
  • devServer.port 指定端口号
  • devServer.proxy 开启代理

image.png

6 webpack生产环境配置

生产环境中mode需要配置成production

image.png

1.提取 css 成单独文件

需要用到mini-css-extract-plugin,经过css-loader的处理,css文件已经被整合到js中,这个我们需要的是把这些css 提取成一个单独的css文件,ini-css-extract-plugin插件loader的作用就是提取js中的css成单独的文件

  • 编写文件 image.png

image.png

image.png

  • 下载插件 npm install --save-dev mini-css-extract-plugin@0.9.0

注:由于很多下载版本过高,都会导致后面运行webpack报错,后面下载就直接加上版本号

  • 配置文件

image.png

  • 结果 image.png

2. css 兼容性处理

css 兼容性处理主要是针对css3 的样式,加上前缀操作,我们需要下载postcss-loader postcss-preset-env,然后在package.json中配置browserslist,postcss通过找到package.json中browserslist里面的配置加载指定的css兼容性样式。

  • 编写文件 略
  • 下载loader npm install --save-dev postcss-loader postcss-preset-env
  • 配置文件

image.png

  • package.json中配置browserslist

image.png

              // 开发环境
              //last 1 代表兼容到最后一个版本
              "development": [
                "last 1 chrome version",
                "last 1 firefox version",
                "last 1 safari version"
              ],
              // 生产环境:默认是看生产环境
              "production": [
                ">0.2%",
                "not dead",
                "not op_mini all"
              ]
            }

3. 压缩css

  • 下载 npm install --save-dev optimize-css-assets-webpack-plugin
  • 配置文件

image.png

4. js 语法检查

js 语法检查的大概过程是 下载 eslint-loader eslint eslint-config-airbnb-base eslint-plugin-import,下载后配置webpack.config.js配置文件,其中需要注意的是我们只需要对我们手写的js语法检查,node_modules中的js是不需要语法检查的,因此需要排除这个文件夹,另外需要在package.json中配置中 eslintConfig以便按照这个规则来进行语法检查,而我们使用的是airbnb的规范,因此上面还安装了eslint-config-airbnb-base。

  • 下载 npm install --save-dev eslint-loader eslint eslint-config-airbnb-base eslint-plugin-import
  • 配置文件

image.png

  • 配置package.json
"eslintConfig": {
     "extends": "airbnb-base",
      "env": {
         "browser": true 
        }
  }

5. js 压缩

生产环境下只需要设置 mode: 'production',会自动压缩 js 代码

6. html 压缩

html压缩用到的是html-webpack-plugin插件

  • 下载 npm install --save-dev html-webpack-plugin
  • 配置文件

image.png

怎么办,周五了,正在写文章的我心早已飞走啦,可是还有好多内容没写啊,不行,我要下班啦,有时间会接着更新哦,看都看了,别忘了给我点个赞哦,谢谢帅哥美女啦哈哈。

7. webpack优化环境配置

1. HMR(热模块替换)

HMR功能一个模块发生变化,只会重新打包这一个模块(而不是打包所有模块),能够极大地提升构建速度。 样式文件:可以使用HMR功能:因为style-loader内部实现了

js文件:默认不能使用HMR功能,需要修改js代码,添加支持HMR功能的代码,并且只能处理非入口文件开启HMR功能

html文件: 默认不能使用HMR功能,同时会导致问题:html文件不能热更新了,解决办法是修改entry入口,将html文件引入

image.png

2. source-map

source-map是一种提供源代码到构建后代码映射的技术,也就是说当构建够的代码出错的时候,可以定位到源代码出错的位置

[inline-|hidden-|eval-][nosources-][cheap-[module-]]source-map

其中,字段代表的含义如下

inline:内联,不生成单独的外部文件

hidden:不追踪源代码错误

eval:每一个文件都生成一个内联的source-map

nosources:无源代码信息

cheap:错误信息只能精确到行

module:module会将loader的source map因引入

按照以上组合source-map可以是:

source-map:外部

错误代码准确信息 和 源代码的错误位置

inline-source-map:内联

只生成一个内联source-map

错误代码准确信息 和 源代码的错误位置

hidden-source-map:外部

错误代码错误原因,但是没有错误位置

不能追踪源代码错误,只能提示到构建后代码的错误位置

eval-source-map:内联

每一个文件都生成对应的source-map,都在eval

错误代码准确信息 和 源代码的错误位置

nosources-source-map:外部

错误代码准确信息, 但是没有任何源代码信息

cheap-source-map:外部

错误代码准确信息 和 源代码的错误位置

只能精确的行

cheap-module-source-map:外部

错误代码准确信息 和 源代码的错误位置

module会将loader的source map加入

内联 和 外部的区别:1. 外部生成了文件,内联没有 2. 内联构建速度更快

开发环境:速度快,调试更友好

速度快(eval>inline>cheap>...)

eval-cheap-souce-map

eval-source-map

调试更友好

souce-map

cheap-module-souce-map

cheap-souce-map

生产环境:源代码要不要隐藏? 调试要不要更友好

内联会让代码体积变大,所以在生产环境不用内联

nosources-source-map 全部隐藏

hidden-source-map 只隐藏源代码,会提示构建后代码错误信息

image.png

3. oneOf

webpack正常情况下会遍历rules中所有的loader,但一般情况下只有一个文件类型是匹配的,使用oneOf 根据文件类型加载对应的loader,只要能匹配一个即可退出。对于同一类型文件,比如处理js,如果需要多个loader,可以单独抽离js处理,确保oneOf里面一个文件类型对应一个loader,并且可通过配置 enforce: 'pre',指定优先执行

image.png

4. 缓存

缓存一般是开启babel缓存(由于这块比较耗时),和文件资源缓存

babel缓存:让第二次打包构建速度更快

文件资源缓存:文件资源缓存中涉及到三种类型的hash

  • hash: 每次wepack构建时会生成一个唯一的hash值

问题:因为js和css同时使用一个hash值。如果重新打包,会导致所有缓存失效。(可能我却只改动一个文件)

  • chunkhash:根据chunk生成的hash值。如果打包来源于同一个chunk,那么hash值就一样

问题: js和css的hash值还是一样的因为css是在js中被引入的,所以同属于一个chunk

  • contenthash: 根据文件的内容生成hash值。不同文件hash值一定不一样

image.png

image.png

5. tree shaking

tree shaking的作用是删除没用到的代码,减少代码体积

trees shaking 的前提:production环境下并且使用ES6模块化

配置:package.json中配置"sideEffects": false,表示所有代码都没有副作用(所有代码都可以tree shaking),但是这样的话可能会存在一些问题,例如会把css / @babel/polyfill (副作用)文件也tree shaking掉,因此我们可以这样配置 "sideEffects": ["*.css", "*.less"],意思是告诉webpack只有这些文件有副作用,所有其他文件都可以 tree-shaking,但会保留这些文件

6. code split(代码分割)

code split将一个庞大的js文件划分成多个小的js文件,从而实现并行加载,让速度更快。比如在vue单页应用中,若不做任何处理,所有vue文件会打包为一个文件,这个文件非常的大,造成网页在首次进入时比较缓慢,此时就可以通过代码分割,提升加载速度。

  • 通过多入口实现代码分割

image.png

  • 通过optimization将公共代码单独打包

image.png

  • import动态导入

image.png

7. 多进程打包

当项目比较庞大的时候,可以通过tread loader开启多进程打包,但是如果是小项目的话则没有必要开启多线程打包,因为开启多线程打包本身启动大概为600ms,这样有可能比以前没开启多线程打包之前花的时间更长

image.png

8. externals

防止将某一些包打包到我们最终的bundle里面从而导致包体积变大

image.png

image.png

9. dll

使用dll技术,对某些库(第三方库:jquery、react、vue...)进行单独打包,例如一般情况下node_modules 里面的包会打包成一个chunk,但是第三方库很大,打包成一个chunk文件体积过大,可以通过 dll 将所有库进行单独打包成不同的chunk,更加有利于我们的性能优化,提高构建速度

  • 新建 webpack.dll.js 文件

image.png

image.png

  • webpack文件配置

image.png

10.懒加载和预加载

  • 懒加载:当文件需要使用时才加载

image.png

  • 预加载 prefetch:等其他资源加载完毕,浏览器空闲了,再偷偷加载资源

注意:兼容性比较差,慎用

在懒加载的基础上,添加webpackPrefetch:true设置为预加载

image.png

8. 结尾

终于更新完啦,如果看了对你有帮助的, 欢迎点个赞👍和关注哦,谢谢喽