• <legend id="kntsb"></legend>
  • <track id="kntsb"></track>
    <span id="kntsb"><output id="kntsb"><b id="kntsb"></b></output></span>
  • <span id="kntsb"><blockquote id="kntsb"><nav id="kntsb"></nav></blockquote></span>
      <legend id="kntsb"></legend><span id="kntsb"><output id="kntsb"></output></span>

      杭州PHP培訓
      達內杭州PHP培訓中心

      0571-56020837

      2020年前端面試題匯總之Webpack

      • 時間:2021-04-02 14:05
      • 發布:杭州PHP培訓
      • 來源:php面試題

      今天小編要跟大家分享的文章是關于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弓長張 總在落幕后

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

      預約申請免費試聽課

      怕錢不夠?就業掙錢后再付學費!    怕學不會?從入學起,達內定制課程!     擔心就業?達內多家實踐企業供你挑選!

      上一篇:2020年前端面試題匯總之常見性能優化
      下一篇:沒有下一篇了

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

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

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

      2021Web前端面試題及答案匯總-Javascript篇

      • 關注微信公眾號

        回復關鍵字:視頻資料

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

      • 視頻學習QQ群

        添加QQ群:1143617948

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

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

      選擇城市和中心
      江西省

      貴州省

      廣西省

      海南省

      天天爱搞搞狠狠爱 天天射天天日天天舔 狠狠在线插口日日干