webpack面試知識(shí)點(diǎn)

有哪些常見的Loader劲弦?你用過哪些Loader?

  • raw-loader:加載文件原始內(nèi)容(utf-8)
  • file-loader:把文件輸出到一個(gè)文件夾中华畏,在代碼中通過相對(duì) URL 去引用輸出的文件 (處理圖片和字體)
  • url-loader:與 file-loader 類似,區(qū)別是用戶可以設(shè)置一個(gè)閾值,大于閾值時(shí)返回其 publicPath歧譬,小于閾值時(shí)返回文件 base64 形式編碼 (處理圖片和字體)
  • svg-inline-loader:將壓縮后的 SVG 內(nèi)容注入代碼中
  • image-loader:加載并且壓縮圖片文件
  • json-loader:加載 JSON 文件(默認(rèn)包含)
  • handlebars-loader: 將 Handlebars 模版編譯成函數(shù)并返回
  • style-loader:把 CSS 代碼注入到 JavaScript 中,通過 DOM 操作去加載 CSS
  • postcss-loader:擴(kuò)展 CSS 語法搏存,使用下一代 CSS瑰步,可以配合 autoprefixer 插件自動(dòng)補(bǔ)齊 CSS3 前綴
  • sass-loader將SCSS/SASS代碼轉(zhuǎn)換成CSS
  • css-loader加載 CSS,支持模塊化璧眠、壓縮缩焦、文件導(dǎo)入等特性
  • source-map-loader加載額外的 Source Map 文件读虏,以方便斷點(diǎn)調(diào)試
  • babel-loader把 ES6 轉(zhuǎn)換成 ES5
  • ts-loader: 將 TypeScript 轉(zhuǎn)換成 JavaScript
  • awesome-typescript-loader:將 TypeScript 轉(zhuǎn)換成 JavaScript,性能優(yōu)于 ts-loader
  • eslint-loader通過 ESLint 檢查 JavaScript 代碼
  • tslint-loader通過 TSLint檢查 TypeScript 代碼
  • vue-loader加載 Vue.js 單文件組件
  • mocha-loader:加載 Mocha 測試用例的代碼
  • coverjs-loader:計(jì)算測試的覆蓋率
  • i18n-loader: 國際化
  • cache-loader: 可以在一些性能開銷較大的 Loader 之前添加袁滥,目的是將結(jié)果緩存到磁盤里

更多 Loader 請(qǐng)參考官網(wǎng)

有哪些常見的Plugin盖桥?你用過哪些Plugin?(加粗部分為webpack提速相關(guān)插件)

  • define-plugin:定義環(huán)境變量 (Webpack4 之后指定 mode 會(huì)自動(dòng)配置)
  • ignore-plugin:忽略部分文件
  • html-webpack-plugin:簡化 HTML 文件創(chuàng)建 (依賴于 html-loader)
  • web-webpack-plugin:可方便地為單頁應(yīng)用輸出 HTML题翻,比 html-webpack-plugin 好用
  • mini-css-extract-plugin: 分離樣式文件揩徊,CSS 提取為獨(dú)立文件,支持按需加載 (替代extract-text-webpack-plugin)
  • serviceworker-webpack-plugin:為網(wǎng)頁應(yīng)用增加離線緩存功能
  • clean-webpack-plugin: 目錄清理
  • uglifyjs-webpack-plugin不支持 ES6 壓縮 (Webpack4 以前)
  • terser-webpack-plugin: 支持壓縮 ES6 (Webpack4)
  • webpack-parallel-uglify-plugin: 多進(jìn)程執(zhí)行代碼壓縮嵌赠,提升構(gòu)建速度
  • ModuleConcatenationPlugin: 開啟 Scope Hoisting
  • speed-measure-webpack-plugin: 可以看到每個(gè) Loader 和 Plugin 執(zhí)行耗時(shí) (整個(gè)打包耗時(shí)塑荒、每個(gè) Plugin 和 Loader 耗時(shí))
  • webpack-bundle-analyzer: 可視化 Webpack 輸出文件的體積 (業(yè)務(wù)組件、依賴第三方模塊)

更多 Plugin 請(qǐng)參考官網(wǎng)

Loader和Plugin的區(qū)別

Loader 本質(zhì)就是一個(gè)函數(shù)猾普,在該函數(shù)中對(duì)接收到的內(nèi)容進(jìn)行轉(zhuǎn)換袜炕,返回轉(zhuǎn)換后的結(jié)果。因?yàn)?Webpack 只認(rèn)識(shí) JavaScript初家,所以 Loader 就成了翻譯官偎窘,對(duì)其他類型的資源進(jìn)行轉(zhuǎn)譯的預(yù)處理工作。

Plugin 就是插件溜在,基于事件流框架 Tapable陌知,插件可以擴(kuò)展 Webpack 的功能,在 Webpack 運(yùn)行的生命周期中會(huì)廣播出許多事件掖肋,Plugin 可以監(jiān)聽這些事件仆葡,在合適的時(shí)機(jī)通過 Webpack 提供的 API 改變輸出結(jié)果。

Loader 在 module.rules 中配置志笼,作為模塊的解析規(guī)則沿盅,類型為數(shù)組。每一項(xiàng)都是一個(gè) Object纫溃,內(nèi)部包含了 test(類型文件)腰涧、loader、options (參數(shù))等屬性紊浩。

Plugin 在 plugins 中單獨(dú)配置窖铡,類型為數(shù)組,每一項(xiàng)是一個(gè) Plugin 的實(shí)例坊谁,參數(shù)都通過構(gòu)造函數(shù)傳入费彼。

Webpack構(gòu)建流程

Webpack 的運(yùn)行流程是一個(gè)串行的過程,從啟動(dòng)到結(jié)束會(huì)依次執(zhí)行以下流程:

  • 初始化參數(shù):從配置文件和 Shell 語句中讀取與合并參數(shù)口芍,得出最終的參數(shù)
  • 開始編譯:用上一步得到的參數(shù)初始化 Compiler 對(duì)象箍铲,加載所有配置的插件,執(zhí)行對(duì)象的 run 方法開始執(zhí)行編譯
  • 確定入口:根據(jù)配置中的 entry 找出所有的入口文件
  • 編譯模塊:從入口文件出發(fā)鬓椭,調(diào)用所有配置的 Loader 對(duì)模塊進(jìn)行翻譯虹钮,再找出該模塊依賴的模塊聋庵,再遞歸本步驟直到所有入口依賴的文件都經(jīng)過了本步驟的處理
  • 完成模塊編譯:在經(jīng)過第4步使用 Loader 翻譯完所有模塊后,得到了每個(gè)模塊被翻譯后的最終內(nèi)容以及它們之間的依賴關(guān)系
  • 輸出資源:根據(jù)入口和模塊之間的依賴關(guān)系芙粱,組裝成一個(gè)個(gè)包含多個(gè)模塊的 Chunk,再把每個(gè) Chunk 轉(zhuǎn)換成一個(gè)單獨(dú)的文件加入到輸出列表氧映,這步是可以修改輸出內(nèi)容的最后機(jī)會(huì)
  • 輸出完成:在確定好輸出內(nèi)容后春畔,根據(jù)配置確定輸出的路徑和文件名,把文件內(nèi)容寫入到文件系統(tǒng)

在以上過程中岛都,Webpack 會(huì)在特定的時(shí)間點(diǎn)廣播出特定的事件律姨,插件在監(jiān)聽到感興趣的事件后會(huì)執(zhí)行特定的邏輯,并且插件可以調(diào)用 Webpack 提供的 API 改變 Webpack 的運(yùn)行結(jié)果臼疫。

簡單說:

  • 初始化:啟動(dòng)構(gòu)建择份,讀取與合并配置參數(shù),加載 Plugin烫堤,實(shí)例化 Compiler
  • 編譯:從 Entry 出發(fā)荣赶,針對(duì)每個(gè) Module 串行調(diào)用對(duì)應(yīng)的 Loader 去翻譯文件的內(nèi)容,再找到該 Module 依賴的 Module鸽斟,遞歸地進(jìn)行編譯處理
  • 輸出:將編譯后的 Module 組合成 Chunk拔创,將 Chunk 轉(zhuǎn)換成文件,輸出到文件系統(tǒng)中

使用webpack開發(fā)時(shí)富蓄,你用過哪些可以提高效率的插件剩燥?

  • webpack-dashboard:可以更友好的展示相關(guān)打包信息。
  • webpack-merge:提取公共配置立倍,減少重復(fù)配置代碼
  • speed-measure-webpack-plugin:簡稱 SMP晒他,分析出 Webpack 打包過程中 Loader 和 Plugin 的耗時(shí),有助于找到構(gòu)建過程中的性能瓶頸罢缸。
  • size-plugin:監(jiān)控資源體積變化分俯,盡早發(fā)現(xiàn)問題
  • HotModuleReplacementPlugin:模塊熱替換

source map是什么?生產(chǎn)環(huán)境怎么用疆导?

source map 是將編譯赁项、打包、壓縮后的代碼映射回源代碼的過程澈段。打包壓縮后的代碼不具備良好的可讀性悠菜,想要調(diào)試源碼就需要 soucre map。

map文件只要不打開開發(fā)者工具败富,瀏覽器是不會(huì)加載的悔醋。

線上環(huán)境一般有三種處理方案:

  • hidden-source-map:借助第三方錯(cuò)誤監(jiān)控平臺(tái) Sentry 使用
  • nosources-source-map:只會(huì)顯示具體行數(shù)以及查看源代碼的錯(cuò)誤棧。安全性比 sourcemap 高
  • sourcemap:通過 nginx 設(shè)置將 .map 文件只對(duì)白名單開放(公司內(nèi)網(wǎng))

注意:避免在生產(chǎn)中使用 inline-eval-兽叮,因?yàn)樗鼈儠?huì)增加 bundle 體積大小芬骄,并降低整體性能猾愿。

模塊打包原理

Webpack 把解析的所有模塊變成一個(gè)對(duì)象,然后通過入口模塊去加載我們的東西账阻,然后依次實(shí)現(xiàn)遞歸的依賴關(guān)系蒂秘,通過入口來運(yùn)行所有的文件。Webpack 實(shí)際上為每個(gè)模塊創(chuàng)造了一個(gè)可以導(dǎo)出和導(dǎo)入的環(huán)境淘太,本質(zhì)上并沒有修改代碼的執(zhí)行邏輯姻僧,代碼執(zhí)行順序與模塊加載順序也完全一致。

文件監(jiān)聽原理

在發(fā)現(xiàn)源碼發(fā)生變化時(shí)蒲牧,自動(dòng)重新構(gòu)建出新的輸出文件撇贺。

Webpack開啟監(jiān)聽模式,有兩種方式:

  • 啟動(dòng) webpack 命令時(shí)冰抢,帶上 --watch 參數(shù)
  • 在配置 webpack.config.js 中設(shè)置 watch:true

缺點(diǎn):每次需要手動(dòng)刷新瀏覽器

原理:輪詢判斷文件的最后編輯時(shí)間是否變化松嘶,如果某個(gè)文件發(fā)生了變化,并不會(huì)立刻告訴監(jiān)聽者挎扰,而是先緩存起來翠订,等 aggregateTimeout 后再執(zhí)行。

module.export = {
    // 默認(rèn)false,也就是不開啟
    watch: true,
    // 只有開啟監(jiān)聽模式時(shí)鼓鲁,watchOptions才有意義
    watchOptions: {
        // 默認(rèn)為空蕴轨,不監(jiān)聽的文件或者文件夾,支持正則匹配
        ignored: /node_modules/,
        // 監(jiān)聽到變化發(fā)生后會(huì)等300ms再去執(zhí)行骇吭,默認(rèn)300ms
        aggregateTimeout:300,
        // 判斷文件是否發(fā)生變化是通過不停詢問系統(tǒng)指定文件有沒有變化實(shí)現(xiàn)的橙弱,默認(rèn)每秒問1000次
        poll:1000
    }
}

Webpack 熱更新原理

Webpack 的熱更新又稱熱替換(Hot Module Replacement),縮寫為 HMR燥狰。這個(gè)機(jī)制可以做到不用刷新瀏覽器而將新變更的模塊替換掉舊的模塊棘脐。

HMR的核心就是客戶端從服務(wù)端拉去更新后的文件,準(zhǔn)確的說是 chunk diff (chunk 需要更新的部分)龙致,實(shí)際上 Webpack-dev-server (WDS) 與瀏覽器之間維護(hù)了一個(gè) Websocket(websocket 可建立本地服務(wù)和瀏覽器的雙向通信蛀缝。),本地文件發(fā)生變化時(shí)目代,會(huì)通知瀏覽器熱更新代碼屈梁。

具體地說就是,當(dāng)本地資源發(fā)生變化時(shí)榛了,WDS 會(huì)向?yàn)g覽器推送更新在讶,并帶上構(gòu)建時(shí)的 hash,讓客戶端與上一次資源進(jìn)行對(duì)比霜大」共福客戶端對(duì)比出差異后會(huì)向 WDS 發(fā)起 Ajax 請(qǐng)求來獲取更改內(nèi)容(文件列表、hash)战坤,這樣客戶端就可以再借助這些信息繼續(xù)向 WDS 發(fā)起 jsonp 請(qǐng)求獲取該chunk的增量更新曙强。

后續(xù)的部分(拿到增量更新之后如何處理残拐?哪些狀態(tài)該保留?哪些又需要更新碟嘴?)由 HotModulePlugin 來完成溪食,提供了相關(guān) API 以供開發(fā)者針對(duì)自身場景進(jìn)行處理,像react-hot-loadervue-loader 都是借助這些 API 實(shí)現(xiàn) HMR娜扇。具體可在這里了解

文件指紋是什么眠菇?怎么用?

文件指紋是打包后輸出的文件名的后綴袱衷。

  • Hash:和整個(gè)項(xiàng)目的構(gòu)建相關(guān),只要項(xiàng)目文件有修改笑窜,整個(gè)項(xiàng)目構(gòu)建的 hash 值就會(huì)更改
  • Chunkhash:和 Webpack 打包的 chunk 有關(guān)致燥,不同的 entry 會(huì)生出不同的 chunkhash
  • Contenthash:根據(jù)文件內(nèi)容來定義 hash,文件內(nèi)容不變排截,則 contenthash 不變

JS的文件指紋設(shè)置

設(shè)置 output 的 filename嫌蚤,用 chunkhash。

module.exports = {
    entry: {
        app: './scr/app.js',
        search: './src/search.js'
    },
    output: {
        filename: '[name][chunkhash:8].js',
        path:__dirname + '/dist'
    }
}

CSS的文件指紋設(shè)置

設(shè)置 MiniCssExtractPlugin 的 filename断傲,使用 contenthash脱吱。

module.exports = {
    entry: {
        app: './scr/app.js',
        search: './src/search.js'
    },
    output: {
        filename: '[name][chunkhash:8].js',
        path:__dirname + '/dist'
    },
    plugins:[
        new MiniCssExtractPlugin({
            filename: `[name][contenthash:8].css`
        })
    ]
}

圖片的文件指紋設(shè)置

設(shè)置file-loader的name,使用hash认罩。

占位符名稱及含義

  • ext 資源后綴名
  • name 文件名稱
  • path 文件的相對(duì)路徑
  • folder 文件所在的文件夾
  • contenthash 文件的內(nèi)容hash箱蝠,默認(rèn)是md5生成
  • hash 文件內(nèi)容的hash,默認(rèn)是md5生成
  • emoji 一個(gè)隨機(jī)的指代文件內(nèi)容的emoj
const path = require('path');

module.exports = {
    entry: './src/index.js',
    output: {
        filename:'bundle.js',
        path:path.resolve(__dirname, 'dist')
    },
    module:{
        rules:[{
            test:/\.(png|svg|jpg|gif)$/,
            use:[{
                loader:'file-loader',
                options:{
                    name:'img/[name][hash:8].[ext]'
                }
            }]
        }]
    }
}

在實(shí)際工程中垦垂,配置文件上百行乃是常事宦搬,如何保證各個(gè)loader按照預(yù)想方式工作?

可以使用 enforce 強(qiáng)制執(zhí)行 loader 的作用順序劫拗,pre 代表在所有正常 loader 之前執(zhí)行间校,post 是所有 loader 之后執(zhí)行。(inline 官方不推薦使用)

如何對(duì)bundle體積進(jìn)行監(jiān)控和分析页慷?

VSCode 中有一個(gè)插件 Import Cost 可以幫助我們對(duì)引入模塊的大小進(jìn)行實(shí)時(shí)監(jiān)測憔足,還可以使用 webpack-bundle-analyzer 生成 bundle 的模塊組成圖,顯示所占體積酒繁。

bundlesize 工具包可以進(jìn)行自動(dòng)化資源體積監(jiān)控滓彰。

如何優(yōu)化 Webpack 的構(gòu)建速度?

  • 多進(jìn)程/多實(shí)例構(gòu)建:HappyPack(不維護(hù)了)欲逃、thread-loader
  • 多進(jìn)程并行壓縮
    • webpack-paralle-uglify-plugin(不再維護(hù))
    • uglifyjs-webpack-plugin 開啟 parallel 參數(shù) (不支持ES6)
    • terser-webpack-plugin 開啟 parallel 參數(shù)(支持ES6)
  • DLL
    • 使用 DllPlugin 進(jìn)行對(duì)第三方庫分包提前打包找蜜,使用 DllReferencePlugin(索引鏈接) 對(duì) manifest.json 引用,讓一些基本不會(huì)改動(dòng)的代碼先打包成靜態(tài)資源稳析,通過 json 文件告訴webpack這些庫提前打包好了洗做,避免反復(fù)編譯浪費(fèi)時(shí)間弓叛。
    • HashedModuleIdsPlugin 可以解決模塊數(shù)字id問題
  • 充分利用緩存提升二次構(gòu)建速度
    • babel-loader 開啟緩存
    • terser-webpack-plugin 開啟緩存
    • 使用 cache-loader 或者 hard-source-webpack-plugin
  • 縮小構(gòu)建目標(biāo)/減少文件搜索范圍
    • exclude(不需要被解析的模塊)/include(需要被解析的模塊)
    • resolve.modules 告訴 webpack 解析模塊時(shí)搜索的目錄,指明第三方模塊的絕對(duì)路徑
    • resolve.mainFields 限定模塊入口文件名诚纸,只采用 main 字段作為入口文件描述字段 (減少搜索步驟撰筷,需要考慮到所有運(yùn)行時(shí)依賴的第三方模塊的入口文件描述字段)
    • resolve.alias 當(dāng)從 npm 包中導(dǎo)入模塊時(shí)(例如,import * as React from 'react')畦徘,此選項(xiàng)將決定在 package.json 中使用哪個(gè)字段導(dǎo)入模塊毕籽。根據(jù) webpack 配置中指定的 target 不同,默認(rèn)值也會(huì)有所不同
    • resolve.extensions 盡可能減少后綴嘗試的可能性
    • noParse 對(duì)完全不需要解析的庫進(jìn)行忽略 (不去解析但仍會(huì)打包到 bundle 中井辆,注意被忽略掉的文件里不應(yīng)該包含 import关筒、require、define 等模塊化語句)
    • IgnorePlugin (完全排除模塊)
  • 動(dòng)態(tài)Polyfill
    • 通過 Polyfill Service識(shí)別 User Agent杯缺,下發(fā)不同的 Polyfill蒸播,做到按需加載,社區(qū)維護(hù)萍肆。(部分國內(nèi)奇葩瀏覽器UA可能無法識(shí)別袍榆,但可以降級(jí)返回所需全部polyfill)
  • Scope hoisting (「作用域提升」)
    • 構(gòu)建后的代碼會(huì)存在大量閉包,造成體積增大塘揣,運(yùn)行代碼時(shí)創(chuàng)建的函數(shù)作用域變多包雀,內(nèi)存開銷變大。Scope hoisting 把引入的 js 文件“提升到”它的引入者頂部亲铡,其實(shí)現(xiàn)原理為:分析出模塊之間的依賴關(guān)系才写,盡可能的把打散的模塊合并到一個(gè)函數(shù)中去,但前提是不能造成代碼冗余奴愉。因此只有那些被引用了一次的模塊才能被合并琅摩。
    • 必須是ES6的語法,因?yàn)橛泻芏嗟谌綆烊圆捎?CommonJS 語法和 Scope Hoisting 要分析模塊之間的依賴關(guān)系锭硼,需要配置 mainFields 對(duì)第三方模塊優(yōu)先采用 jsnext:main 中指向的ES6模塊化語法
  • 提取頁面公共資源
    • 使用 html-webpack-externals-plugin房资,將基礎(chǔ)包通過 CDN 引入,不打入 bundle 中
    • 使用 SplitChunksPlugin 進(jìn)行(公共腳本檀头、基礎(chǔ)包轰异、頁面公共文件)分離(Webpack4內(nèi)置) ,替代了 CommonsChunkPlugin 插件
    • 基礎(chǔ)包分離
  • Tree shaking
    • purgecss-webpack-plugin 和 mini-css-extract-plugin配合使用(建議)
    • 打包過程中檢測工程中沒有引用過的模塊并進(jìn)行標(biāo)記暑始,在資源壓縮時(shí)將它們從最終的bundle中去掉(只能對(duì)ES6 Modlue生效) 開發(fā)中盡可能使用ES6 Module的模塊搭独,提高tree shaking效率
    • 禁用 babel-loader 的模塊依賴解析,否則 Webpack 接收到的就都是轉(zhuǎn)換過的 CommonJS 形式的模塊廊镜,無法進(jìn)行 tree-shaking
    • 使用 PurifyCSS(不在維護(hù)) 或者 uncss 去除無用 CSS 代碼

更多優(yōu)化請(qǐng)參考官網(wǎng)-構(gòu)建性能

代碼分割的本質(zhì)是什么牙肝?有什么意義呢?

代碼分割的本質(zhì)其實(shí)就是在源代碼直接上線打包成唯一腳本main.bundle.js這兩種極端方案之間的一種更適合實(shí)際場景的中間狀態(tài)。

「用可接受的服務(wù)器性能壓力增加來換取更好的用戶體驗(yàn)配椭〕媪铮」

  • 源代碼直接上線:雖然過程可控,但是http請(qǐng)求多股缸,性能開銷大衡楞。
  • 打包成唯一腳本:一把梭完自己爽,服務(wù)器壓力小敦姻,但是頁面空白期長瘾境,用戶體驗(yàn)不好。

是否寫過Loader镰惦?簡單描述一下編寫loader的思路迷守?

Loader 支持鏈?zhǔn)秸{(diào)用,所以開發(fā)上需要嚴(yán)格遵循“單一職責(zé)”旺入,每個(gè) Loader 只負(fù)責(zé)自己需要負(fù)責(zé)的事情盒犹。

Loader的API 可以去官網(wǎng)查閱

  • Loader 運(yùn)行在 Node.js 中,我們可以調(diào)用任意 Node.js 自帶的 API 或者安裝第三方模塊進(jìn)行調(diào)用
  • Webpack 傳給 Loader 的原內(nèi)容都是 UTF-8 格式編碼的字符串眨业,當(dāng)某些場景下 Loader 處理二進(jìn)制文件時(shí),需要通過 exports.raw = true 告訴 Webpack 該 Loader 是否需要二進(jìn)制數(shù)據(jù)
  • 盡可能的異步化 Loader沮协,如果計(jì)算量很小龄捡,同步也可以
  • Loader 是無狀態(tài)的,我們不應(yīng)該在 Loader 中保留狀態(tài)
  • 使用 loader-utils 和 schema-utils 為我們提供的實(shí)用工具
  • 加載本地 Loader 方法
    • Npm link
    • ResolveLoader

是否寫過Plugin慷暂?簡單描述一下編寫Plugin的思路聘殖?

webpack在運(yùn)行的生命周期中會(huì)廣播出許多事件,Plugin 可以監(jiān)聽這些事件行瑞,在特定的階段鉤入想要添加的自定義功能奸腺。Webpack 的 Tapable 事件流機(jī)制保證了插件的有序性,使得整個(gè)系統(tǒng)擴(kuò)展性良好血久。

Plugin的API 可以去官網(wǎng)查閱

  • compiler 暴露了和 Webpack 整個(gè)生命周期相關(guān)的鉤子
  • compilation 暴露了與模塊和依賴有關(guān)的粒度更小的事件鉤子
  • 插件需要在其原型上綁定apply方法突照,才能訪問 compiler 實(shí)例
  • 傳給每個(gè)插件的 compiler 和 compilation對(duì)象都是同一個(gè)引用,若在一個(gè)插件中修改了它們身上的屬性氧吐,會(huì)影響后面的插件
  • 找出合適的事件點(diǎn)去完成想要的功能
    • emit 事件發(fā)生時(shí)讹蘑,可以讀取到最終輸出的資源、代碼塊筑舅、模塊及其依賴座慰,并進(jìn)行修改(emit 事件是修改 Webpack 輸出資源的最后時(shí)機(jī))
    • watch-run 當(dāng)依賴的文件發(fā)生變化時(shí)會(huì)觸發(fā)
  • 異步的事件需要在插件處理完任務(wù)時(shí)調(diào)用回調(diào)函數(shù)通知 Webpack 進(jìn)入下一個(gè)流程,不然會(huì)卡住

聊一聊Babel原理吧

大多數(shù)JavaScript Parser遵循 estree 規(guī)范翠拣,Babel 最初基于 acorn 項(xiàng)目(輕量級(jí)現(xiàn)代 JavaScript 解析器)版仔,Babel 是對(duì)瀏覽器識(shí)別不了的代碼進(jìn)行轉(zhuǎn)換兼容的庫,Babel大概分為三大部分:

  • Parser 解析:將代碼轉(zhuǎn)換成抽象語法樹 (AbstractSyntaxTree,簡稱 AST)
    • 詞法分析:將字符串形式的代碼分割為令牌(token)流蛮粮,即語法單元成的數(shù)組
    • 語法分析:將token流轉(zhuǎn)換成 AST
  • Transformer 轉(zhuǎn)換:根據(jù)配置好的 plugins/presetsParser 生成的 AST 轉(zhuǎn)變?yōu)樾碌?AST
    • Taro就是利用 babel 完成的小程序語法轉(zhuǎn)換
  • Generator 生成:把新的 AST 生成代碼

想了解如何一步一步實(shí)現(xiàn)一個(gè)編譯器的同學(xué)可以移步 Babel 官網(wǎng)曾經(jīng)推薦的開源項(xiàng)目the-super-tiny-compiler

參考

「吐血整理」再來一打Webpack面試題

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末益缎,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子蝉揍,更是在濱河造成了極大的恐慌链峭,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,635評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件又沾,死亡現(xiàn)場離奇詭異弊仪,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)杖刷,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,543評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門励饵,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人滑燃,你說我怎么就攤上這事役听。” “怎么了表窘?”我有些...
    開封第一講書人閱讀 168,083評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵典予,是天一觀的道長。 經(jīng)常有香客問我乐严,道長瘤袖,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,640評(píng)論 1 296
  • 正文 為了忘掉前任昂验,我火速辦了婚禮捂敌,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘既琴。我一直安慰自己占婉,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,640評(píng)論 6 397
  • 文/花漫 我一把揭開白布甫恩。 她就那樣靜靜地躺著逆济,像睡著了一般。 火紅的嫁衣襯著肌膚如雪磺箕。 梳的紋絲不亂的頭發(fā)上纹腌,一...
    開封第一講書人閱讀 52,262評(píng)論 1 308
  • 那天,我揣著相機(jī)與錄音滞磺,去河邊找鬼升薯。 笑死,一個(gè)胖子當(dāng)著我的面吹牛击困,可吹牛的內(nèi)容都是我干的涎劈。 我是一名探鬼主播广凸,決...
    沈念sama閱讀 40,833評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼蛛枚!你這毒婦竟也來了谅海?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,736評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤蹦浦,失蹤者是張志新(化名)和其女友劉穎扭吁,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體盲镶,經(jīng)...
    沈念sama閱讀 46,280評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡侥袜,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,369評(píng)論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了溉贿。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片枫吧。...
    茶點(diǎn)故事閱讀 40,503評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖宇色,靈堂內(nèi)的尸體忽然破棺而出九杂,到底是詐尸還是另有隱情,我是刑警寧澤宣蠕,帶...
    沈念sama閱讀 36,185評(píng)論 5 350
  • 正文 年R本政府宣布例隆,位于F島的核電站,受9級(jí)特大地震影響抢蚀,放射性物質(zhì)發(fā)生泄漏裳擎。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,870評(píng)論 3 333
  • 文/蒙蒙 一思币、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧羡微,春花似錦谷饿、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,340評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至盯蝴,卻和暖如春毅哗,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背捧挺。 一陣腳步聲響...
    開封第一講書人閱讀 33,460評(píng)論 1 272
  • 我被黑心中介騙來泰國打工虑绵, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人闽烙。 一個(gè)月前我還...
    沈念sama閱讀 48,909評(píng)論 3 376
  • 正文 我出身青樓翅睛,卻偏偏與公主長得像声搁,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子捕发,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,512評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容

  • 盒模型: 基本概念:標(biāo)準(zhǔn)模型 + IE模型 標(biāo)準(zhǔn)模型 和 IE模型的區(qū)別標(biāo)準(zhǔn)盒模型不包括padding和borde...
    谷子多閱讀 505評(píng)論 1 1
  • 寫在前面的話 閱讀本文之前疏旨,先看下面這個(gè)webpack的配置文件,如果每一項(xiàng)你都懂扎酷,那本文能帶給你的收獲也許就比較...
    不忘初心_9a16閱讀 3,242評(píng)論 0 17
  • 隨著現(xiàn)代前端開發(fā)的規(guī)模日益龐大檐涝,幾乎已經(jīng)不能拋開諸如 React 或 Vue 等前端開發(fā)框架來獨(dú)立開發(fā)了,這些框架...
    limengzhe閱讀 978評(píng)論 0 7
  • 1.有哪些常見的Loader法挨?他們是解決什么問題的谁榜? file-loader:把文件輸出到一個(gè)文件夾中,在代碼中通...
    猴逃逃閱讀 177評(píng)論 0 0
  • 久違的晴天坷剧,家長會(huì)惰爬。 家長大會(huì)開好到教室時(shí),離放學(xué)已經(jīng)沒多少時(shí)間了惫企。班主任說已經(jīng)安排了三個(gè)家長分享經(jīng)驗(yàn)撕瞧。 放學(xué)鈴聲...
    飄雪兒5閱讀 7,524評(píng)論 16 22