乐趣区

关于前端:前端面试宝典webpack核心知识篇

前言:

想零碎学习前端面试题,强烈推荐浏览 在线电子书(反对手机版,不断更新)。

本书特点:零碎全面(涵盖前端核心技术点),简洁,针对性强(针对面试场景设计)。

欢送在 github 上留言反馈

webpack

[TOC]

webpack 外面的插件是怎么实现的?

Compiler(编译器)和 Compilation(编译办法)

在开发 Plugin 时最罕用的两个对象就是 Compiler 和 Compilation,它们是 Plugin 和 Webpack 之间的桥梁。
Compiler 和 Compilation 的含意如下:

  • Compiler: 对象蕴含了 Webpack 环境所有的的配置信息,蕴含 options,loaders,plugins 这些信息,这个对象在 Webpack 启动时候被实例化,它是全局惟一的,能够简略地把它了解为 Webpack 实例;
  • Compilation: 对象蕴含了以后的模块资源、编译生成资源、变动的文件等。当 Webpack 以开发模式运行时,每当检测到一个文件变动,一次新的 Compilation 将被创立。Compilation 对象也提供了很多事件回调供插件做扩大。通过 Compilation 也能读取到 Compiler 对象。

Compiler 和 Compilation 的区别在于:

Compiler 代表了整个 Webpack 从启动到敞开的生命周期,而 Compilation 只是代表了一次新的编译。

插件运行机制:

参考资料:

Webpack 原理 - 编写 Plugin

webpack 打包过程?

一)初始化阶段:

二)编译阶段:

三)输入阶段:

webpack 的运行流畅是一个串行过程,过程如下:

  • 始化参数:从配置文件和 Shell 语句中读取与合并参数,得出最终的参数;
  • 开始编译:用上一步失去的参数初始化 Compiler 对象,加载所有配置的插件,执行对象的 run 办法开始执行编译;
  • 确定入口:依据配置中的 entry 找出所有的入口文件;
  • 编译模块:从入口文件登程,调用所有配置的 Loader 对模块进行翻译,再找出该模块依赖的模块,再递归本步骤直到所有入口依赖的文件都通过了本步骤的解决;
  • 实现模块编译:在通过第 4 步应用 Loader 翻译完所有模块后,失去了每个模块被翻译后的最终内容以及它们之间的依赖关系;
  • 输入资源:依据入口和模块之间的依赖关系,组装成一个个蕴含多个模块的 Chunk,再把每个 Chunk 转换成一个独自的文件退出到输入列表,这步是能够批改输入内容的最初机会;
  • 输入实现:在确定好输入内容后,依据配置确定输入的门路和文件名,把文件内容写入到文件系统。

同时咱们也理解了 webpack 中比拟外围的几个概念 compiler、compilation、tapable。

参考资料:webpack 编译流程

组件库按需加载如何实现?

一)实现形式

1) 通过装置 babel-plugin-import (举荐)

.babelrc or babel-loader option

{
 "plugins":[
     ["import":{
       {libraryName:"antd-mobile",style:"css"   //style:true 会加载 less 文件}
     }]
 ]
}

2) 手动引入

import DatePicker from "antd-mobile/lib/date-picket";
import "antd-mobile/lib/date-picker/style/css"
//import "antd-mobile/lib/date-picker/style"    // 加载 less

二)反对的库

  • antd
  • antd-mobile
  • loadsh
  • material-ui

三) 实现原理

动静引入 css, 和模块,最终编译的成果就是本义成 手动引入的成果

配置项:{“libraryName”: “antd”, style: “css”}

style 参数阐明:

  • css:间接引入通过打包后的 antd 款式文件
  • true:在我的项目编译阶段,对引入的 antd 款式文件进行编译,从而可压缩打包尺寸
import {Button} from 'antd';
ReactDOM.render(<Button>xxxx</Button>);

      ↓ ↓ ↓ ↓ ↓ ↓

var _button = require('antd/lib/button');
require('antd/lib/button/style/css');
ReactDOM.render(<_button>xxxx</_button>);

参考资料:babel-plugin-import 的配置项

webpack 外围概念?

Entry: 指定 webpack 开始构建的入口模块,从该模块开始构建并计算出间接或间接依赖的模块或者库。

Output:通知 webpack 如何命名输入的文件以及输入的目录

Module: 模块,在 Webpack 里所有皆模块,一个模块对应着一个文件。Webpack 会从配置的 Entry 开始递归找出所有依赖的模块。

Chunkcoding split的产物,咱们能够对一些代码打包成一个独自的 chunk,比方某些公共模块,去重,更好的利用缓存。或者按需加载某些功能模块,优化加载工夫。在webpack3 及以前咱们都利用 CommonsChunkPlugin 将一些公共代码宰割成一个 chunk,实现独自加载。在webpack4CommonsChunkPlugin 被废除,应用SplitChunksPlugin

Loader:模块转换器,用于把模块原内容依照需要转换成新内容。

Plugin:扩大插件,在 Webpack 构建流程中的特定时机会播送出对应的事件,插件能够监听这些事件的产生,在特定机会做对应的事件。

参考资料:

webpack 编译流程

webpack 如何进步打包速度?

一、放大文件搜寻范畴

  1. 排除:loader 的时候排除不必要的文件,比方 node,modules
  2. 别名定位:设置文件别名,alias, 防止文件层层解析,疾速定位
  3. 缩小文件查找:合理配置 resolve.extensions(匹配尽量少,高频类型放后面,导入文件加后缀)

二、提取公共模块:应用 dllPlugin 提取共用专用模块,打包出 vendor.js, 防止反复编译

三、开过程转换:HappyPack 开启多过程 loader 转换

四、开过程压缩:应用 paralleUglifyPlugin 开启多过程压缩 JS 文件

五、利用缓存:webpack.cache、babel-loader.cacheDirectory、HappyPack.cache都能够利用缓存进步 rebuild 效率

参考资料:

应用 webpack4 晋升 180% 编译速度

webpack 与 rollup 打包工具比照区别?

相同点:webpack 与 rollup 都是用来打包我的项目的;

理论应用:开发利用时用 webpack, 开发库时应用 rollup;

区别:

webpack:次要用来打包工程项目,次要它是通过将模块别离关闭进函数中,构建进去的代码体积较大;

性能特点:

  • 代码宰割
  • 动态资源导入
  • 模块热更新 HMR;

rollup:下一代 ES6 模块化工具,次要用来打包类库(library), 用标准化的格局 es6 来写代码,构建进去的代码体积更小,更污浊;react,vue 目前就是用 rollup 打包的;

webpack 罕用的 babel,loader,plugin 有哪些?

babel:宽泛的转码器,(es6/ts 代码转成 es5 代码)

  • 只转换新的语法(箭头函数)
  • 不转换新的 API(promise,proxy,set,symbol)须要另外装置 poliy

loader:加载更类资源文件

  • css 类 —- less-loader,sass-loader, postcss-loader,autoprefixer-loader
  • 文件类 —- url-loader,file-loader

plugin:插件

  • webpack-dev-server (小型 node express 服务器)
  • postcss-plugin-px2rem

动态页面如何应用,webpack 来实现自动更新?

1. 创立 npm 配置文件 package.json

{

  "name": "demo",

  "version": "1.0.0",

  "description": "","main":"index.js","scripts": {​    "test": "echo \"Error: no test specified\"&& exit 1"},

  "author": "","license":"ISC"

}

2. 装置 webpack

3. 装置 webpack-dev-server

webpack-dev-server 有什么用,如何配置?

webpack-dev-server 是一个小型的 express 服务器,应用它能够为 webpack 生成的资源文件提供 web 服务;

次要性能:

  1. 为动态文件提供 http 服务
  2. 主动刷新新热替换(HMR)

装置

先装置好

npm i webpack-dev-server

第一:webpack-dev–server 能够用来生成 localhost:8080 在线地址的网站,生成站点域名;

间接运行命令

webpack-dev-server // 通过这个地址能够间接拜访(然而地址地址栏有尾巴,并且内容区域顶部有内容)

或者通过这个来指定门路,去掉尾部和 url 不优雅的中央

–contentbase src 指定门路(监控 src 内容的变动,src 下放的是 bundle.js)

–inline 把 webpack-dev-server 之前默认的 iframe 默认批改成 inlinie 模式,这样页面就不会有多余的内容了;

webpack-dev-server –contentbase src –inline

第二:webpack 热更新,性能是在页面内容发生变化后会主动刷新页面;

webpack-dev-server –contentbase src –inline –hot

你对 webpack 做过哪些配置?

除了惯例咱们援用的各种 file loader,plugin,babel 配置次要还有三方面的优化:

一、放慢打包速度方面(见专题答复)

二、优化开发体验

  • 主动刷新:启用 webpack-dev-server 主动刷新文件;(轮训工夫,排除的文件夹,构建延迟时间)
  • 热替换:开启模块替换 HMR,不刷新页面替换内容;

三、优化输入品质

  • 压缩文件体积
  • 应用 cdn 减速动态资源
  • 宰割代码以按需加载
  • 多页面利用提取页面间公共组件
  • 辨别生产 / 测试环境

参考资料:

webpack 做过哪些优化,开发效率方面、打包策略方面等等

Babel

什么是 babel?

babel 是一个宽泛的转码器,能够把 es6/ 7 等最新的语法转换成 es5 的语法,让浏览器可能兼容;

babel 的配置文件 .babelrc 次要有两个配置:

  • 转码规定 presets
  • 插件 plugins

babel 是如何把 es6 代码转换成 es5 代码的?

babel 将 es6 代码转换成 es5,次要有三个阶段;

  1. 【解析 Parse】把 es6 代码,通过 babylon 解析成,AST 语法树,即词法剖析与语法分析的过程
  2. 【转换 Transform】通过 babel-traverse plugin 对 AST 树进行遍历转译,在此过程中进行增加 / 更新 / 删除等操作,生成新的 AST
  3. 【生成 Generate】通过 babel-generator,将变换后的 AST 再转成 es5 代码

注意事项:babel 默认不转换的代码须要通过装置 babelpolyfill 来反对,比方:

  • Array.from,generator,set,maps,proxy,symbol…

如何写一个 babel 插件?

实现流程

  1. babel 解析成 AST
  2. 而后插件更改 AST(Babel 的插件的模块须要裸露一个 function, 在 function 内返回 visitor)
  3. 最初 Babel 输入代码
退出移动版