2020年你不能不知道的webpack基本配置

前言

在好久好久之前,在咱們前端還只是頁面切圖仔的年代,咱們開發一個html頁面,一般會遇到這些狀況:css

  • 須要引入十幾個css和js文件,並且由於他們彼此間有着依賴關係,因此引入的順序還不能亂。
  • 傳統的html+css+js開發方式不能不能很好地運用less/scss等css預處理器以及ES6+的高級語法。
  • 代碼複用性差,可維護性差。

此時就須要一個處理這些問題的工具,webpack應運而生。html

webpack能夠看作是模塊打包工具:它將各類靜態資源(好比:javaScript 文件,圖片文件,css文件等)視爲模塊,它可以對這些模塊進行解析優化和轉換等操做,最後將它們打包在一塊兒,打包後的文件可用於在瀏覽器中使用。前端

相關推薦vue

本人github: github.com/Michael-lzg
個人掘金:https://juejin.im/user/5b52fd...
從零開始構建一個webpack項目
總結幾個webpack打包優化的方法java

webpack的優勢:

  • 代碼轉換: typeScript 編譯成 javaScriptscss,less 編譯成 css.
  • 文件優化:壓縮 javaScriptcsshtml 代碼,壓縮合並圖片。
  • 代碼分割:提取多個頁面的公共代碼、提取首屏不須要執行部分的代碼讓其異步加載。
  • 模塊合併:在採用模塊化的項目裏會有不少個模塊和文件,須要構建功能把模塊分類合併成一個文件。
  • 自動刷新:監聽本地源代碼的變化,自動從新構建、刷新瀏覽器。
  • 擴展性強,插件機制完善。

webpack打包過程:

1.利用babel完成代碼轉換,並生成單個文件的依賴
2.從入口開始遞歸分析,並生成依賴圖譜
3.將各個引用模塊打包爲一個當即執行函數
4.將最終的bundle文件寫入bundle.js中node

Webpack 的四大核心:

  • entry:js 入口源文件
  • output:生成文件
  • loader:進行文件處理
  • plugins:插件,比 loader 更強大,能使用更多 webpack 的 api

Entry

webpack 應該使用哪一個模塊作爲入口文件,來做爲構建其內部依賴圖的開始。進去入口起點後,webpack 會找出有哪些模塊和庫是入口起點(直接和間接)依賴的,每一個依賴項隨即被處理,最後輸出到稱之爲 bundles 的文件中。webpack

單⼊⼝:entry 是⼀個字符串git

module.exports = {
  entry: './src/index.js'
}

多⼊⼝:entry 是⼀個對象github

module.exports = {
  entry: {
    index: './src/index.js',
    manager: './src/manager.js'
  }
}

Output

告訴 webpack 在哪裏輸出它所建立的 bundles,以及如何命名這些文件,這些均可以在webpack的配置文件中指定。web

單⼊⼝配置

module.exports = {
    entry: './src/index.js',
    output: {
        filename: 'bundle.js’,
        path: __dirname + '/dist'
    }
};

多⼊⼝配置

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

經過[name]佔位符確保⽂件名稱的惟⼀

Loader

loaderwebpack 可以去處理那些非 javaScript 文件(webpack 自身只理解 javaScript)。loader 能夠將全部類型的文件轉換爲 webpack 可以處理的有效模塊,而後你就能夠利用 webpack 的打包能力,對它們進行處理。

loader的特色

  • 一個Loader 的職責是單一的,只須要完成一種轉換
  • 一個Loader 其實就是一個Node.js 模塊,這個模塊須要導出一個函數
  • loader 老是從右到左地被調用。

經常使用的loader

處理樣式

  • css-loader: 加載.css 文件,
  • style-loader:使用 style 標籤將 css-loader 內部樣式注入到咱們的 html 頁面
  • less-loader, sass-loader: 解析css預處理器

處理 js

  • 讓你能使用最新的js代碼(ES6,ES7...)
  • 讓你能使用基於js進行了拓展的語言,好比React的JSX;

處理文件

處理圖片資源時,咱們經常使用的兩種loader是file-loader或者url-loader,二者的主要差別在於。url-loader能夠設置圖片大小限制,當圖片超過限制時,其表現行爲等同於file-loader,而當圖片不超過限制時,則會將圖片以base64的形式打包進css文件,以減小請求次數

處理.vue文件

vue-loaderwebpack 的加載器模塊,它使咱們能夠用 .vue 文件格式編寫單文件組件。單文件組件文件有三個部分,即模板、腳本和樣式。 vue-loader 模塊容許 webpack 使用單獨的加載器模塊(例如 sass 或 scss 加載器)提取和處理每一個部分。該設置使咱們可使用 .vue 文件無縫編寫程序。

開發一個loader

需求:手寫一個 loader,將 'kobe' 轉換成 'Black Mamba'。固然你們能夠根據本身的需求進行設計。這裏只是講解方法。

一、編寫 loader

在根目錄下,新建目錄 kobe-loader 做爲咱們編寫 loader 的名稱,執行 npm init -y 命令,新建一個模塊化項目,而後新建 index.js 文件,相關源碼以下:

module.exports = function(content) {
  return content && content.replace(/kobe/gi, 'Black Mamba')
}

二、註冊模塊

正常咱們安裝的 loader 是從 npm 下載安裝,可是咱們能夠在 kobe-loader 目錄底下使用 npm link 作到在不發佈模塊的狀況下,將本地的一個正在開發的模塊的源碼連接到項目的 node_modules 目錄下,讓項目能夠直接使用本地的 npm 模塊。

npm link

而後在項目根目錄執行如下命令,將註冊到全局的本地 npm 模塊連接到項目的 node_modules

$ npm link kobe-loader

註冊成功後,咱們能夠在 node_modules 目錄下能查找到對應的 loader

三、在 webpack 中配置 loader

webpack.base.conf.js 加上以下配置

{
  test:/\.js/,
  loader: 'kobe-loader'
}

此時,咱們在全部 js 文件下書寫的 'kobe' 就所有替換成 'Black Mamba'了。

四、配置參數

上面咱們是寫死的替換文案,假如我想經過配置項來改變,能夠在 loader 中作如下調整

// custom-loader/index.js
var utils = require('loader-utils')
module.exports = function (content) {
  const options = utils.getOptions(this)
  return content && content.replace(/kobe/gi, options.name)
}

// webpack.base.conf.js
{
  test:/\.js/,
  use: {
    loader: 'kobe-loader',
    options: {
      name: 'kobe',
    }
  }
}

Plugin

專一處理 webpack 在編譯過程當中的某個特定的任務的功能模塊,能夠稱爲插件。

Plugin 的特色

  • 是一個獨立的模塊
  • 模塊對外暴露一個 js 函數
  • 函數的原型 (prototype) 上定義了一個注入 compiler 對象的 apply方法 apply 函數中須要有經過 compiler 對象掛載的 webpack 事件鉤子,鉤子的回調中能拿到當前編譯的 compilation 對象,若是是異步編譯插件的話能夠拿到回調 callback
  • 完成自定義子編譯流程並處理 complition 對象的內部數據
  • 若是異步編譯插件的話,數據處理完成後執行 callback 回調。

經常使用Plugin

  • HotModuleReplacementPlugin 代碼熱替換。由於 Hot-Module-Replacement 的熱更新是依賴於 webpack-dev-server,後者是在打包文件改變時更新打包文件或者 reload 刷新整個頁面,HRM 是隻更新修改的部分。
  • HtmlWebpackPlugin, 生成 html 文件。將 webpack 中entry配置的相關入口 chunk 和 extract-text-webpack-plugin抽取的 css 樣式 插入到該插件提供的template或者templateContent配置項指定的內容基礎上生成一個 html 文件,具體插入方式是將樣式link插入到head元素中,script插入到head或者body中。
  • ExtractTextPlugin, 將 css 成生文件,而非內聯 。該插件的主要是爲了抽離 css 樣式,防止將樣式打包在 js 中引發頁面樣式加載錯亂的現象。
  • NoErrorsPlugin報錯但不退出 webpack 進程
  • UglifyJsPlugin,代碼醜化,開發過程當中不建議打開。 uglifyJsPlugin 用來對 js 文件進行壓縮,從而減少 js 文件的大小,加速 load 速度。uglifyJsPlugin 會拖慢 webpack 的編譯速度,全部建議在開發簡單將其關閉,部署的時候再將其打開。多個 html 共用一個 js 文件(chunk),可用 CommonsChunkPlugin
  • purifycss-webpack  。打包編譯時,可剔除頁面和 js 中未被使用的 css,這樣使用第三方的類庫時,只加載被使用的類,大大減少 css 體積
  • optimize-css-assets-webpack-plugin   壓縮 css,優化 css 結構,利於網頁加載和渲染
  • webpack-parallel-uglify-plugin   能夠並行運行 UglifyJS 插件,這能夠有效減小構建時間

開發一個 plugin

  • Webpack 在編譯過程當中,會廣播不少事件,例如 run、compile、done、fail 等等,能夠查看官網;
  • Webpack 的事件流機制應用了觀察者模式,咱們編寫的插件能夠監聽 Webpack 事件來觸發對應的處理邏輯;
  • 插件中可使用不少 Webpack 提供的 API,例如讀取輸出資源、代碼塊、模塊及依賴等;

一、編寫插件

在根目錄下,新建目錄 my-plugin 做爲咱們編寫插件的名稱,執行 npm init -y 命令,新建一個模塊化項目,而後新建 index.js 文件,相關源碼以下:

class MyPlugin {
  constructor(doneCallback, failCallback) {
    // 保存在建立插件實例時傳入的回調函數
    this.doneCallback = doneCallback
    this.failCallback = failCallback
  }
  apply(compiler) {
    // 成功完成一次完整的編譯和輸出流程時,會觸發 done 事件
    compiler.plugin('done', stats => {
      this.doneCallback(stats)
    })
    // 在編譯和輸出的流程中遇到異常時,會觸發 failed 事件
    compiler.plugin('failed', err => {
      this.failCallback(err)
    })
  }
}
module.exports = MyPlugin

二、註冊模塊

按照以上的方法,咱們在 my-plugin 目錄底下使用 npm link 作到在不發佈模塊的狀況下,將本地的一個正在開發的模塊的源碼連接到項目的 node_modules 目錄下,讓項目能夠直接使用本地的 npm 模塊。

npm link

而後在項目根目錄執行如下命令,將註冊到全局的本地 npm 模塊連接到項目的 node_modules 下

$ npm link my-plugin

註冊成功後,咱們能夠在 node_modules 目錄下能查找到對應的插件了。

三、配置插件

在 webpack.base.conf.js 加上以下配置

plugins: [
  new MyPlugin(
    stats => {
      console.info('編譯成功!')
    },
    err => {
      console.error('編譯失敗!')
    }
  )
]

執行運行 or 編譯命令,就能看到咱們的 plugin 起做用了。

推薦文章

從零開始構建一個webpack項目
總結幾個webpack打包優化的方法
總結移動端H5開發經常使用技巧
總結前端性能優化的方法
搭建一個vue-cli的移動端H5開發模板
封裝一個toast和dialog組件併發布到npm
一文讀盡前端路由、後端路由、單頁面應用、多頁面應用
淺談JavaScript的防抖與節流

關注的個人公衆號不按期分享前端知識,與您一塊兒進步!

相關文章
相關標籤/搜索