webpack面試題

webpack

談談你對webpack的見解

webpack是一個模塊打包工具,可使用它管理項目中的模塊依賴,並編譯輸出模塊所需的靜態文件。它能夠很好地管理、打包開發中所用到的HTML,CSS,JavaScript和靜態文件(圖片,字體)等,讓開發更高效。對於不一樣類型的依賴,webpack有對應的模塊加載器,並且會分析模塊間的依賴關係,最後合併生成優化的靜態資源。css

webpack的基本功能和工做原理?

  • 代碼轉換:TypeScript 編譯成 JavaScript、SCSS 編譯成 CSS 等等
  • 文件優化:壓縮 JavaScript、CSS、HTML 代碼,壓縮合並圖片等
  • 代碼分割:提取多個頁面的公共代碼、提取首屏不須要執行部分的代碼讓其異步加載
  • 模塊合併:在採用模塊化的項目有不少模塊和文件,須要構建功能把模塊分類合併成一個文件
  • 自動刷新:監聽本地源代碼的變化,自動構建,刷新瀏覽器
  • 代碼校驗:在代碼被提交到倉庫前須要檢測代碼是否符合規範,以及單元測試是否經過
  • 自動發佈:更新完代碼後,自動構建出線上發佈代碼並傳輸給發佈系統。

webpack構建過程

  • 從entry裏配置的module開始遞歸解析entry依賴的全部module
  • 每找到一個module,就會根據配置的loader去找對應的轉換規則
  • 對module進行轉換後,再解析出當前module依賴的module
  • 這些模塊會以entry爲單位分組,一個entry和其全部依賴的module被分到一個組Chunk
  • 最後webpack會把全部Chunk轉換成文件輸出
  • 在整個流程中webpack會在恰當的時機執行plugin裏定義的邏輯

webpack打包原理

將全部依賴打包成一個bundle.js,經過代碼分割成單元片斷按需加載html

什麼是webpack,與gulp,grunt有什麼區別

  • webpack是一個模塊打包工具,能夠遞歸地打包項目中的全部模塊,最終生成幾個打包後的文件。
  • 區別:webpack支持代碼分割,模塊化(AMD,CommonJ,ES2015),全局分析

什麼是entry,output?

  • entry 入口,告訴webpack要使用哪一個模塊做爲構建項目的起點,默認爲./src/index.js
  • output 出口,告訴webpack在哪裏輸出它打包好的代碼以及如何命名,默認爲./dist

什麼是loader,plugins?

  • loader是用來告訴webpack如何轉換某一類型的文件,而且引入到打包出的文件中。
  • plugins(插件)做用更大,能夠打包優化,資源管理和注入環境變量

什麼是bundle,chunk,module?

bundle是webpack打包出來的文件,chunk是webpack在進行模塊的依賴分析的時候,代碼分割出來的代碼塊。module是開發中的單個模塊前端

如何自動生成webpack配置?

能夠用一些官方腳手架vue

  • webpack-cli
  • vue-cli
// 首先安裝
npm install -g @vue/cli
// 新建項目hello
vue create hello
複製代碼
  • nuxt-cli
// 確保安裝了npx,npx在npm5.2.0默認安裝了
// 新建項目hello
npx create-nuxt-app hello
複製代碼

webpack如何配置單頁面和多頁面的應用程序?

  • 單個頁面
module.exports = {
    entry: './path/to/my/entry/file.js'
}
複製代碼
  • 多頁面應用程序
module.entrys = {
    entry: {
        pageOne: './src/pageOne/index.js',
        pageTwo: './src/pageTwo/index.js'
    }
}
複製代碼

webpack-dev-server和http服務器如nginx有什麼區別?

webpack-dev-server使用內存來存儲webpack開發環境下的打包文件,而且可使用模塊熱更新,相比傳統http服務器開發更加簡單高效node

什麼是模塊熱更新?

webpack的一個功能,可使代碼修改後不用刷新瀏覽器就自動更新,高級版的自動刷新瀏覽器webpack

dev-server是怎麼跑起來的

webpack-dev-server支持兩種模式來自動刷新頁面nginx

  • iframe模式(頁面放在iframe中,當發送改變時重載) 無需額外配置,只要以這種格式url訪問便可。http://localhost:8080/webpack-dev-server/index.html
  • inline模式(將webpack-dev-server的客戶端入口添加到bundle中) inline模式下url不用發生變化,但啓動inline模式分兩種狀況
// 以命令行啓動webpack-dev-server有兩種方式
// 方式1 在命令行中添加--inline命令
// 方式2 在webpack-config.js添加devServer:{inline: true}
// 以node.js API啓動有兩種方式
// 方式1 添加webpack-dev-server/client?http://localhost:8080/到webpack配置的entry入口點
config.entry.app.unshift("webpack-dev-server/client?http://localhost:8080/");
// 將<script src="http://localhost:8080/webpack-dev-server.js"></script>添加到html文件中
複製代碼

使用過webpack裏面哪些plugin和loader

loaderweb

  • babel-loader: 將ES6+轉移成ES5-
  • css-loader,style-loader:解析css文件,可以解釋@import url()等
  • file-loader:直接輸出文件,把構建後的文件路徑返回,能夠處理不少類型的文件
  • url-loader:打包圖片
// url-loader加強版的file-loader,小於limit的轉爲Base64,大於limit的調用file-loader
npm install url-loader -D
// 使用
module.exports = {
    module: {
        rules: [{
            test: /\.(png|jpg|gif)$/,
            use: [{
                loader: 'url-loader',
                options: {
                    outputPath: 'images/',
                    limit: 500 //小於500B的文件打包出Base64格式,寫入JS
                }
            }]
        }]
    }
}
複製代碼

plugins面試

  • html-webpack-plugin: 壓縮html
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
  //...
  plugins: [
    new HtmlWebpackPlugin({
      filename: 'index.html', // 配置輸出文件名和路徑
      template: './public/index.html', // 配置要被編譯的html文件
      hash: true,
      // 壓縮 => production 模式使用
      minify: {
        removeAttributeQuotes: true, //刪除雙引號
        collapseWhitespace: true //摺疊 html 爲一行
      }
    })
  ]
}
複製代碼
  • clean-webpack-plugin: 打包器清理源目錄文件,在webpack打包器清理dist目錄
npm install clean-webpack-plugin -D
// 修改webpack.config.js
const cleanWebpackPlugin=require('clean-webpack-plugin')
module.exports = {
    plugins: [new cleanWebpackPlugin(['dist'])]
}
複製代碼

webpack中babel的實現

安裝 npm i -D @babel-preset-env @babel-core babel-loadervue-cli

  • @babel-preset-env:可讓咱們靈活設置代碼目標執行環境
  • @babel-core: babel核心庫
  • babel-loader: webpack的babel插件,讓咱們能夠在webpack中運行babel

配置.babelrc

{
    "presets": ['@babel/preset-env']
}
複製代碼

配置webpack.config.js

module.exports = {
    entry: './src/index.js',
    output: {
        path: path.resolve(__dirname, 'dist'),
        filename: 'bundle.js'
    },
    module: {
        rules: [{
            test: /\.js$/,
            exclude: /node_modules/,
            use: {loader: 'babel-loader'}
        }]
    }
}
複製代碼

提取公用代碼

module.exports = {
    optimization: {
        splitChunks: {
            common: {
                // 抽離公共代碼
                chunks: 'initial',
                name: 'common', // 打包後的文件名
                minChunks: 2, // 最小引用2次
                minSize: 0 // 超出0字節就生成一個新包
            },
            styles: {
                // 抽離公用代碼
                name: 'styles',
                test: /\.css$/,
                chunks: 'all',
                minChunks: 2,
                enforce: true
            },
            vender: {
                // 抽離第三方插件
                test: /node_modules/,
                chunks: 'initial',
                name: 'vendor', // 打包後的文件名
                priority: 10 // 設置優先級,防止與自定義公共代碼提取時被覆蓋,不進行打包
            }
        }
    }
}
複製代碼

什麼是長緩存?在webpack中如何作到長緩存優化?

  • 瀏覽器在用戶訪問頁面的時候,爲了加快加載速度會對用戶訪問的靜態資源進行存儲,可是每一次代碼升級或更新都須要瀏覽器下載新的代碼,最簡單方便的方式就是引入新的文件名稱。
  • webpack中能夠在output中指定chunkhash,而且分離常常更新的代碼和框架代碼。經過NameModulesPlugin或HashedModuleIdsPlugin使再次打包文件名不變。

什麼是Tree-shaking?CSS能夠Tree-shaking?

Tree-shaking是指在打包中取出那些引入了但在代碼中沒有被用到的死代碼。webpack中經過uglifysPlugin來Tree-shaking JS。CSS須要使用purify-CSS

繼承 8種

原型鏈繼承

  • 重點:子的原型對象爲new一個父的實例 Child.prototype = new Parent();
  • 缺點:多個實例對引用類型的操做會被篡改

借用構造函數繼承

  • 重點:在子構造函數內部調用父構造函數 Parent.call(this)
  • 缺點:沒法實現複用,不能繼承原型屬性/方法

組合繼承

  • 重點:使用原型鏈繼承共享的屬性和方法,經過借用構造函數繼承實例屬性
function Child(name,age){
    // 繼承屬性
    Parent.call(this, name)
    this.age=age
}
// 繼承方法
Child.prototype = new Parent()
Child.prototype.constructor = Child;
複製代碼
  • 缺點:不管在什麼狀況都會調用兩次父構造函數,一次是建立子類型原型,另外一次是在子構造函數內部

原型式繼承

  • 重點:執行對給定對象的淺複製
function object(obj){
    function F(){}
    F.prototype=obj
    return new F();
}
var person1=object(person);
複製代碼

在ES5中Object.create()可替換上面的方法object() var person1 = Object.create(person);

  • 缺點:原型鏈繼承多個實例的引用類型屬性指向相同,存在篡改的可能;沒法傳遞參數

寄生式繼承

  • 重點:在原型式繼承的基礎上,加強對象,返回構造函數
function createAnother(obj){
    var clone=object(obj);
    // ES5中用這個
    // var clone=Object.create(obj);
    // 加強對象
    clone.sayHi=function(){};
    return clone;
}
var person1=createAnother(person)
複製代碼
  • 缺點:同原型式繼承

寄生組合式繼承

  • 重點:結合構造函數傳遞參數和寄生模式實現繼承
// 借用構造函數加強子類實例屬性(支持傳參和避免篡改)
function Child(name,age){
    // 繼承屬性
    Parent.call(this, name)
    this.age=age
}
function inheritPrototype(Child, Parent){
    var prototype=Object.create(Parent.prototype);
    prototype.constructor=Child;
    Child.prototype=prototype;
}
// 將父類原型指向子類,這樣子類就能使用父類原型鏈的屬性/方法
inheritPrototype(Child, Parent);
複製代碼

優勢:只調用一次構造函數,原型鏈不變,是最成熟的

混入方式繼承多個方式

重點:利用Object.assign將父類原型上的方法拷貝到子類原型上,這樣子類實例實例就可使用父類的方法

Object.assign(Child.prototype, Parent.prototype);
Child.prototype.constructor=Child;
複製代碼

ES6類 extends

重點:使用extends代表繼承自哪一個父類,而且在子類構造函數中必須使用super,能夠看作是Parent.call(this,value)

class Parent{
    constructor(value){
        this.val=value
    }
}
class Child extends Parent{
    constructor(value){
        super(value)
        this.val = value
    }
}
複製代碼

參考文獻:

相關文章
相關標籤/搜索