webpack学习

webpack是现代前端开发中最火的模块打包工具。
官网:https://www.webpackjs.com/

介绍

WebPack可以看做是模块打包机:

它做的事情是,分析你的项目结构,找到JavaScript模块以及其它的一些浏览器不能直接运行的拓展语言(Scss,TypeScript等),并将其转换和打包为合适的格式供浏览器使用。

WebPack和Grunt以及Gulp相比有什么特性

其实Webpack和另外两个并没有太多的可比性,Gulp/Grunt是一种能够优化前端的开发流程的工具,而WebPack是一种模块化的解决方案,不过Webpack的优点使得Webpack在很多场景下可以替代Gulp/Grunt类的工具。

Grunt和Gulp的工作方式是:在一个配置文件中,指明对某些文件进行类似编译,组合,压缩等任务的具体步骤,工具之后可以自动替你完成这些任务。
Webpack的工作方式是:把你的项目当做一个整体,通过一个给定的主文件(如:index.js),Webpack将从这个文件开始找到你的项目的所有依赖文件,使用loaders处理它们,最后打包为一个(或多个)浏览器可识别的JavaScript文件。

webpack源码

  1. 把所有模块的代码放入到函数中,用一个数组保存起来
  2. 根据require时传入的数组索引,能知道需要哪一段代码
  3. 从数组中,根据索引取出包含我们代码的函数
  4. 执行该函数,传入一个对象Module.exports
  5. 我们的代码,按照约定,正好是用module.exports=’xxx’进行赋值
  6. 调用函数结束后,module.exports从原来的空对象,就有值了
  7. 最终return module.exports作为require函数的返回值

npm install webpack babel-loader --save-dev
配置webpack.config.js
配置package.json 中的scripts
运行npm start

webpack.config.js文件配置:

  1. Entry:指定webpack开始构建的入口模块,从该模块开始构建并计算出直接或间接依赖的模块或者库
  2. Output:告诉webpack如何命名输出的文件以及输出的目录
  3. Module模块(对象)(loaders:[])存在一些loader{test:正则,loader:’style-loader!css-loader’}
    webpack中,loader的配置主要在module.rules中进行,这是一个数组,每一个rule做了两件事

    识别文件类型,来确定具体处理该数据的loader(Rule.test属性)
    使用相关的loader对文件进行相关的操作转换(Rule.use属性)

    常用的loader:

      转换编译:script-loader, babel-loader,ts-loader,coffee-loader
    
      处理样式:style-loader,css-loader,less-loader,sass-loader,postcss-loader
    
      处理文件:raw--loader,url-loader,file-loader
    
      处理数据:csv-loader,xml-loader
    
      处理模板语言:html-loader,pug-loader,jade-loader,markdown-loader
    
      清理和测试:mocha-loader,eslint-loader
    
      此外还有许多loader,可以到loader文档里查询
    处理CSS:require(./xxx.css)
    

处理less:loader:’style-loader!css-loader!less-loader’

Loaders:由于webpack只能处理javascript,所以我们需要对一些非js文件处理成webpack能够处理的模块,比如sass文件

处理ES6:babel-loader+babel-preset-env(se2015/2016/2017)

处理文件+base64:
url-loader可以将文件生成为base64编码。到build.js中
文件在base64加密后会比原来大三分之一
应用场景是比较小的图片 4kb以内的图片

Plugins: Loaders将各类型的文件处理成webpack能够处理的模块, plugins有着很强的能力。插件的范围包括,从打包优化和压缩,一直到重新定义环境中的变量。但也是最复杂的一个。比如对js文件进行压缩优化的 UglifyJsPlugin插件。一种插件就是一种函数,通过传入不同的参数,可以实现不同的功能,webpack让人觉得难学的地方之一是哟啊自己封装plugins,对于我们大多数人来说,需要掌握的plugins并不是那么多,用的时候再查就可以

Chunk:coding split的产物,我们可以对一些代码打包成一个单独的chunk,比如某些公共模块,去重,更好的利用缓存。或者按需加载某些功能模块,优化加载时间。在webpack3及以前我们都利用 CommonsChunkPlugin将一些公共代码分割成一个chunk,实现单独加载。在webpack4 中 CommonsChunkPlugin被废弃,使用 SplitChunksPlugin

5、一些辅助开发的相关属性

  devtool:打包后的代码和原始代码存在较大的差异,此选项控制是否生成以及如何生成sourcemap

  devserver:通过配置devserver选项,可以开启一个本地服务器

  watch:启用watch模式后,webpack将持续监听热河已经解析文件的更改,开发是开启会很方便

  watchoption:用来定制watch模式的选项

  performance:打包后命令行如何展示性能提示,如果超过某个大小是警告还是报错   

字符串内使用的内置变量

name:[name].[ext]
name是获取原文件名,ext是获取原文件名的后缀
output:{path:’绝对路径’//设置产出的资源目录 filename:’build.js’}

使用webpack构建本地服务器webpack-dev-server

让你的浏览器监听你的代码的修改,并自动刷新显示修改后的结果,其实Webpack提供一个可选的本地开发服务器,这个本地服务器基于node.js构建,可以实现你想要的这些功能,不过它是一个单独的组件,在webpack中进行配置之前需要单独安装它作为项目依赖

  1. 安装webpack-dev-server

    npm i webpack-dev-server

  2. 安装cross-env

    npm i cross-env

  3. 安装HTML支持文件

    npm i html-webpack-plugin
    下载,引入,在plugin里面配置,给其Options设置template(参照物)

  4. 配置pack.json文件

    “scripts”: {

        "test": "echo \"Error: no test specified\" && exit 1",
     "build": "cross-env NODE_ENV=production webpack --config webpack.config.js",
    "dev": "cross-env NODE_ENV=development webpack-dev-server --config webpack.config.js"
    

    },

命令:

  • open 自动打开浏览器
  • hot 热替换,不再刷新的情况下替换
  • inline 自动刷新
  • port 9999 指定端口
  • process 显示编译进度

包的分类管理和分类恢复

  1. 安装包的时候,做一个分类的管理

    - 开发依赖devDependencies(打包相关webpack) npm i 包名 -D   
    - 生产依赖dependencies(不包含webpack打包依赖) npm i 包名 -S 
    
  2. 恢复依赖

    • 开发恢复依赖: npm i
    • 生产恢复: npm i –production

webpack.config.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
module.exports = {
entry: './src/index.js',
output:{
filename:'bundle.js',
path:path.resolve(__dirname,'dist')
},
module:{
rules:[// 配置模块loaders,解析规则
{
test:/\.css$/,
use:[
'style-loader',
'css-loader'
]
},{
test:/\.(png|svg|jpg|gif)$/,
use:[
'file-loader'
]
}
]
},
devtool:"source-map",// enum
// 为浏览器开发者工具添加元数据增强调试
plugins:[
// 附加插件列表 ,插件的执行顺序与元素的索引有关
],
}

注:“__dirname”是node.js中的一个全局变量,它指向当前执行脚本所在的目录。

Babel

Babel其实是一个编译JavaScript的平台,它可以编译代码帮你达到以下目的:

让你能使用最新的JavaScript代码(ES6,ES7...),而不用管新标准是否被当前使用的浏览器完全支持;
让你能使用基于JavaScript进行了拓展的语言,比如React的JSX;

Babel的安装与配置

Babel其实是几个模块化的包,其核心功能位于称为babel-core的npm包中,webpack可以把其不同的包整合在一起使用,对于每一个你需要的功能或拓展,你都需要安装单独的包(用得最多的是解析Es6的babel-env-preset包和解析JSX的babel-preset-react包)。

// npm一次性安装多个依赖模块,模块之间用空格隔开
npm install --save-dev babel-core babel-loader babel-preset-env babel-preset-react

Babel的配置

Babel其实可以完全在 webpack.config.js 中进行配置,但是考虑到babel具有非常多的配置选项,在单一的webpack.config.js文件中进行配置往往使得这个文件显得太复杂,因此一些开发者支持把babel的配置选项放在一个单独的名为 “.babelrc” 的配置文件中。我们现在的babel的配置并不算复杂,不过之后我们会再加一些东西,因此现在我们就提取出相关部分,分两个配置文件进行配置(webpack会自动调用.babelrc里的babel配置选项),如下:

面试题

  1. 什么是webpack?

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

在 webpack里一切文件皆模块,通过 Loader 转换文件,通过 Plugin 注入钩子,最后输出由多个模块组合成的文件。webpack专注于构建模块化项目。

  1. Webpack 打包原理是怎样的?
    webpack的运行流程是一个串行的过程,从启动到结束会依次执行以下流程:

    1. 初始化参数 从配置文件和 Shell 语句中读取与合并参数,得出最终的参数
    2. 开始编译 用上一步得到的参数初始Compiler对象,加载所有配置的插件,通过执行对象的run方法开始执行编译
    3. 确定入口 根据配置中的 Entry 找出所有入口文件
    4. 编译模块 从入口文件出发,调用所有配置的 Loader 对模块进行编译,再找出该模块依赖的模块,再递归本步骤直到所有入口依赖的文件都经过了本步骤的处理
    5. 完成模块编译 在经过第4步使用 Loader 翻译完所有模块后, 得到了每个模块被编译后的最终内容及它们之间的依赖关系
    6. 输出资源:根据入口和模块之间的依赖关系,组装成一个个包含多个模块的 Chunk,再将每个 Chunk 转换成一个单独的文件加入输出列表中,这是可以修改输出内容的最后机会
    7. 输出完成:在确定好输出内容后,根据配置确定输出的路径和文件名,将文件的内容写入文件系统中。
    
  2. 什么是 loader,Webpack Loader 的开发及调试过程?

Loader 就像一个翻译员,能将源文件经过转化后输出新的结果,并且一个文件还可以链式地经过多个翻译员翻译。

一个Loader 的职责是单一的,只需要完成一种转换
一个Loader 其实就是一个Node.js 模块,这个模块需要导出一个函数

开发调试:

1. 确保正在开发的本地 Loader 模块的 package.json 已经配置好(最主要的main字段的入口文件指向要正确)
2. 在本地的 Npm 模块根目录下执行 npm link,将本地模块注册到全局
3. 在项目根目录下执行 npm link loader-name ,将第 2 步注册到全局的本地 Npm 模块链接到项目的 node moduels 下,其中的 loader-name 是指在第 1 步的package.json 文件中配置的模块名称
  1. 了解 Webpack Plugin 的实现机制?

Plugin : 专注处理 webpack 在编译过程中的某个特定的任务的功能模块,可以称为插件。

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

Hot Module Replacement(HMR)是 webpack 发展至今引入的最令人兴奋的特性之一 ,当你对代码进行修改并保存后,webpack 将对代码重新打包,并将新的模块发送到浏览器端,浏览器通过新的模块替换老的模块,这样在不刷新浏览器的前提下就能够对应用进行更新。

  1. 知道哪些 Webpack 性能优化的方法?
  • 优化 Loader 配置
  • 优化 resolve.modules 配置
  • 优化 resolve.mainFields 配置
  • 优化 resolve.alias 配置
  • 优化 resolve.extensions 配置
  • 优化 module.noParse 配置
  • 使用 DllPlugin
  • 使用 HappyPack
  • 使用 ParallelUglifyPlugin
  • 优化文件监听的性能
  • Webpack 实现 CDN 的接入
  • 使用 Tree Shaking
  • 提取公共代码
  • 分割代码以按需加载

https://mp.weixin.qq.com/s/dy1u2g9TeCoq2WOdPLqAXw

文章目录
  1. 1. 介绍
    1. 1.1. WebPack和Grunt以及Gulp相比有什么特性
  2. 2. webpack源码
  3. 3. webpack.config.js文件配置:
    1. 3.1. 字符串内使用的内置变量
    2. 3.2. 使用webpack构建本地服务器webpack-dev-server
      1. 3.2.1. 包的分类管理和分类恢复
  4. 4. Babel
    1. 4.1. Babel的安装与配置
      1. 4.1.1. Babel的配置
  • 面试题
  • 本站总访问量 本站访客数人次 ,