更多課程 選擇中心

Web培訓
達內IT學院

400-111-8989

Web培訓

2020年前端面試題匯總之Webpack

  • 發布:Web前端培訓
  • 來源:web前端面試
  • 時間:2020-11-23 17:40

今天小編要跟大家分享的文章是關于2020年前端面試題匯總之Webpack。正在從事web前端工作和想要換工作的小伙伴們來和小編一起看一看吧,希望本篇文章能夠對大家有所幫助。

2020年前端面試題匯總之Webpack

Webpack

1.1 簡介

本質上,webpack 是一個現代 JavaScript 應用程序的靜態模塊打包器(module bundler)。當 webpack 處理應用程序時,它會遞歸地構建一個依賴關系圖(dependency graph),其中包含應用程序需要的每個模塊,然后將所有這些模塊打包成一個或多個 bundle.

1.2 核心概念

入口(entry)

指示 webpack 應該使用哪個模塊,來作為構建其內部依賴圖的開始。進入入口起點后,webpack 會找出有哪些模塊和庫是入口起點(直接和間接)依賴的。

可以通過在 webpack 配置中配置 entry 屬性,來指定一個入口起點(或多個入口起點)。默認值為 ./src。

輸出(output)

output 屬性告訴 webpack 在哪里輸出它所創建的 bundles,以及如何命名這些文件,默認值為 ./dist。基本上,整個應用程序結構,都會被編譯到你指定的輸出路徑的文件夾中。你可以通過在配置中指定一個 output 字段,來配置這些處理過程

loader

loader 讓 webpack 能夠去處理那些非 JavaScript 文件(webpack 自身只理解 JavaScript)。loader 可以將所有類型的文件轉換為 webpack 能夠處理的有效模塊

在更高層面,在 webpack 的配置中 loader 有兩個目標:

test 屬性,用于標識出應該被對應的 loader 進行轉換的某個或某些文件。

use 屬性,表示進行轉換時,應該使用哪個 loader。

注意:Webpack選擇了compose方式,即從右到左執行loader

插件(plugins)

插件的范圍包括,從打包優化和壓縮,一直到重新定義環境中的變量。插件接口功能極其強大,可以用來處理各種各樣的任務。

plugins需要暴露出一個class, 在new WebpackPlugin()的時候通過構造函數傳入這個插件需要的參數,在webpack啟動的時候會先實例化plugin再調用plugin的apply方法,插件需要在apply函數里監聽webpack生命周期里的事件,做相應的處理

模式(mode)

通過選擇 development 或 production 之中的一個,來設置 mode 參數,你可以啟用相應模式下的 webpack 內置的優化

// 多個入口module.exports = {

mode: 'production', entry: {

index: ["./src/index.js"], main: ["./src/main.js"] },

output: { path: path.resolve(__dirname, 'dist'),

filename: 'js/[name].[hash:8].js' },

module: {

rules: [{ test: /\.js$/, // 正則匹配文件名

exclude: '/node_modules/', // 排除

use: ['babel-loader']

} }, plugins: [ // 插件 new copyWebpackPlugin([{

from: path.resolve(__dirname, 'public/static'),

to: path.resolve(__dirname, 'dist'),

ignore: ['index.html']

}])}

1.3 基本流程

解析shell和config中的配置項,用于激活webpack的加載項和插件

webpack初始化工作,包括構建compiler對象,初始化compiler的上下文,loader和file的輸入輸出環境

解析入口js文件,通過對應的工廠方法創建模塊,使用acron生成AST樹并且遍歷AST,處理require的module,如果依賴中包含依賴則遍歷build module,在遍歷過程中會根據文件類型和loader配置找出合適的loader用來對文件進行轉換

調用seal方法,封裝,逐次對每一個module,chunk進行整理,生成編輯后的代碼

1.4 模塊打包

通過fs將模塊讀取成字符串,然后用warp包裹一下,使之成為一個字符串形式的的函數然后調用 vm.runInNewContext 這樣類型的方法,這個字符串會變成一個函數。

這些模塊的函數會被存放在數組里,然后進行解析執行。module和export都是傳入的對象,webpack會實現require函數,去加載其他模塊。

如果是異步模塊,則會通過jsonp的形式去加載該模塊打包好生成的chunk。異步加載模塊可以使用import和require.ensure函數,函數將會返回一個promise。

上面方法都是公共的,可以抽離成模板的js文件,webpack負責做依賴分析,并將模塊讀成函數填充入數組。(這里說的只是js的模塊)

下面附上簡易版的代碼

<!-- 同步模塊 -->var moduleDepList = [ {'./moduleA': 1}, // module[0] 的依賴 他依賴moduleA 且 moduleA的下標在moduleList 中 為 1 {}] function require(id, parentId) { var currentModlueId = parentId !== undefined ? moduleDepList[parentId][id] : id var module = {exports: {}} var moduleFunc = moduleList[currentModlueId] moduleFunc(id => require(id, currentModlueId), module, module.exports) return module.exports}

<!-- 異步模塊 -->var cache = {}

window.__jsonp = function(chunkId, moduleFunc) { var chunk = cache[chunkId] var resolve = chunk[0] var module = {exports: {}} moduleFunc(require, module, module.exports) resolve(module.exports)}

require.ensure = function(chunkId, parentId) { var currentModlueId = parentId !== undefined ? moduleDepList[parentId][chunkId] : chunkId var currentChunk = cache[currentModlueId]

if (currentChunk === undefined) { var $script = document.createElement('script') $script.src = `chunk.${chunkId}.js` document.body.appendChild($script)

var promise = new Promise(function(resolve) { var chunkCache = [resolve] // 數組形式是為了保存promise chunkCache.status = true // 異步模塊加載中 如果有別的包 在 異步加載在模塊 那么下面的 cache[chunkId] = chunkCache }) cache[chunkId].push(promise) return promise }

if (currentChunk.status) { return currentChunk[1] // 這里的promise 這里的就直接返回promise 這樣模塊只會加載一次 } return currentChunk}

代碼地址:https://github.com/zty1205/react-recruit/tree/master/src/_webpack

1.5 熱更新

client 和 server 建立一個 websocket 通信

當有文件發生變動(如fs.watchFile)的時候,webpack編譯文件,并通過 websocket 向client發送一條更新消息

client 根據收到的hash值,通過ajax獲取一個 manifest 描述文件

client 根據manifest 獲取新的JS模塊的代碼

當取到新的JS代碼之后,會更新 modules tree,(installedModules)調用之前通過 module.hot.accept 注冊好的回調,可能是loader提供的,也可能是你自己寫的

manifest: 描述資源文件對應關系如下,打包后的文件擁有了hash值,所以需要進行映射。

{ "a.js": "a.41231243.js"}

1.6 plugin

1.6.1如何開發一個plugin

一個 JavaScript 命名函數。

在插件函數的 prototype 上定義一個 apply 方法。

指定一個綁定到 webpack 自身的事件鉤子。

處理 webpack 內部實例的特定數據。

功能完成后調用 webpack 提供的回調。

tapable 工具,它提供了 webpack 插件接口的支柱

// 一個 JavaScript 命名函數。function plugin() {};

// 在插件函數的 prototype 上定義一個 `apply` 方法。plugin.prototype.apply = function(compiler) { // 指定一個掛載到 webpack 自身的事件鉤子。 compiler.plugin('webpacksEventHook', function(compilation, callback) { callback(); }); // 使用taptable的寫法 //基本寫法 compiler.hooks.someHook.tap(...) //如果希望在entry配置完畢后執行某個功能 compiler.hooks.entryOption.tap(...) //如果希望在生成的資源輸出到output指定目錄之前執行某個功能 compiler.hooks.emit.tap(...)};

官網地址:https://www.webpackjs.com/api/plugins/

1.6.2 Compiler和Compliation 對象和鉤子

對象

compiler 對象代表了完整的 webpack 環境配置。這個對象在啟動 webpack 時被一次性建立,并配置好所有可操作的設置,包括 options,loader 和 plugin。

compilation 對象代表了一次資源版本構建。當運行 webpack 開發環境中間件時,每當檢測到一個文件變化,就會創建一個新的 compilation,從而生成一組新的編譯資源。一個 compilation 對象表現了當前的模塊資源、編譯生成資源、變化的文件、以及被跟蹤依賴的狀態信息。compilation 對象也提供了很多關鍵時機的回調,以供插件做自定義處理時選擇使用

鉤子:總體分成兩大類:Compiler和Compliation

Compiler暴露了和webpack整個生命周期相關的鉤子

Compilation暴露了與模塊和依賴有關的粒度更小的事件鉤子,官方文檔中的說法是模塊會經歷加載(loaded),封存(sealed),優化(optimized),分塊(chunked),哈希(hashed)和重新創建(restored)這幾個典型步驟,從上面的示例可以看到,compilation是Compiler生命周期中的一個步驟,使用compilation相關鉤子的通用寫法為:

compiler.hooks.compilation.tap('SomePlugin',function(compilation, callback){ compilation.hooks.someOtherHook.tap('SomeOtherPlugin,function(){ .... })});

1.6.3 鉤子的類型

同步鉤子

syncHook: 不關心返回值

syncBailHook: 有一個返回值不為null就跳過剩下的邏輯

SyncWaterfallHook: 下一個任務要拿到上一個任務的返回值

SyncLoopHook: 監聽函數返回true表示繼續循環,返回undefine表示結束循環

異步鉤子

AsyncParallelHook: 異步并發執行,仍是單線程

AsyncParallelBailHook: 異步并發執行,有一個失敗了,其他的都不用走了

AsyncSeriesHook: 異步串行執行

AsyncSeriesBailHook: 異步串行執行,有一個返回值不為null就跳過剩下的邏輯

AsyncSeriesWaterfallHook: 異步串行執行,下一個任務要拿到上一個任務的返回值

1.7 常見plugin

clean-webpack-plugin: 在構建之前刪除上一次build的文件夾

copy-webpack-plugin: 復制文件或文件夾到生成后的目錄

extract-text-webpack | mini-css-extract-plugin: 將所有入口的chunk(entry chunks)中引用的 *.css,移動到獨立分離的 CSS 文件

html-webpack-plugin: 將build后生成的資源以標簽的形式嵌入到HTML模板內

hot-module-replacement: 模塊熱更新

1.8 常見loader

babel-loader: 語法,源碼轉換以便能夠運行在當前和舊版本的瀏覽器或其他環境中

css-loader: 配合style-loader可以解析在js中引入的css文件,并以<style>便簽將css-loader內部樣式注入到我們的HTML頁面

file-loader: 可以解析js中require的文件,輸出到輸出目錄并返回 public URL

html-loader: 可以對HTML模板中指定哪個標簽屬性組合(tag-attribute combination)元素應該被此 loader 處理

less-loader: 依賴less,可以將less編譯成css

postcss-loader: 配合一些plugin如cssnano,autoprefixer可以對css進行壓縮,優化,自動補足前綴等

scss-loader: 配合node-scss,可以將scss編譯成css

style-loader: 配合css-loader可以解析在js中引入的css文件,并以<style>便簽將css-loader內部樣式注入到我們的HTML頁面

url-loader: url-loader 功能類似于 file-loader,但是在文件大小(單位 byte)低于指定的限制時,可以返回一個 DataURL(base64)

1.9 常見打包優化

使用dll

移除prefetch, preload,關閉sourceMap

webpack-bundle-analyzer打包分析,將大的模塊可能的移至CDN。打包時間分析使用speed-measure-webpack-plugin

開啟gzip,服務器需要支持

使用多線程:thread-loader或HappyPack

webpack4內置的terser啟動多線程壓縮

對項目進行拆分

推薦文章:https://blog.csdn.net/lunahaijiao/article/details/104509446/

以上就是小編今天為大家分享的關于2020年前端面試題匯總之Webpack的文章,希望本篇文章能夠對想要換工作的web前端工程師們有所幫助,想要了解更多web前端知識記得關注達內web培訓官網,最后祝愿小伙伴們工作順利,成為一名優秀的web前端工程師。

文章來源:原創 const弓長張 總在落幕后

【免責聲明:本文圖片及文字信息均由小編轉載自網絡,旨在分享提供閱讀,版權歸原作者所有,如有侵權請聯系我們進行刪除。】

預約申請免費試聽課

填寫下面表單即可預約申請免費試聽!怕錢不夠?可就業掙錢后再付學費! 怕學不會?助教全程陪讀,隨時解惑!擔心就業?一地學習,可全國推薦就業!

上一篇:Web前端面試必備面試題整理
下一篇:2020年前端面試題匯總之常見性能優化

Web前端面試前需要做的面試準備有哪些

2020年前端面試題匯總之概念

2020年前端面試題匯總之算法和應用

2020年前端面試題匯總之常見性能優化

  • 關注微信公眾號

    回復關鍵字:視頻資料

    免費領取 達內課程視頻學習資料

  • 視頻學習QQ群

    添加QQ群:1143617948

    免費領取達內課程視頻學習資料

Copyright ? 2018 Tedu.cn All Rights Reserved 京ICP備08000853號-56 京公網安備 11010802029508號 達內時代科技集團有限公司 版權所有

選擇城市和中心
黑龍江省

吉林省

河北省

貴州省

云南省

廣西省

海南省

a一天堂网,靑靑青草手机版,免费视频,青娛樂,大香蕉,热热色,原网站,窝窝影院 <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <文本链> <文本链> <文本链> <文本链> <文本链> <文本链>