沐鳴登錄網站_不能不知道的webpack基本配置

前言

在很久很久以前,在我們前端還只是頁面切圖仔的年代,我們開發一個html頁面,通常會遇到這些情況:

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

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

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

相關推薦

本人github: github.com/Michael-lzg
我的掘金:https://juejin.im/user/

webpack的優點:

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

webpack打包過程:

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

Webpack 的四大核心:

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

Entry

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

單⼊⼝:entry 是⼀個字符串

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

多⼊⼝:entry 是⼀個對象

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

Output

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

單⼊⼝配置

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

loader 讓 webpack 能夠去處理那些非 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-loader 是 webpack 的加載器模塊,它使我們可以用 .vue 文件格式編寫單文件組件。單文件組件文件有三個部分,即模板、腳本和樣式。 vue-loader 模塊允許 webpack 使用單獨的加載器模塊(例如 sass 或 scss 加載器)提取和處理每個部分。該設置使我們可以使用 .vue 文件無縫編寫程序。

開發一個loader

需求:手寫一個 loader,將 ‘kobe’ 轉換成 ‘Black Mamba’。當然大家可以根據自己的需求進行設計。這裏只是講解方法。

1、編寫 loader

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

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

2、註冊模塊

正常我們安裝的 loader 是從 npm 下載安裝,但是我們可以在 kobe-loader 目錄底下使用 npm link 做到在不發布模塊的情況下,將本地的一個正在開發的模塊的源碼鏈接到項目的 node_modules 目錄下,讓項目可以直接使用本地的 npm 模塊。

npm link

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

$ npm link kobe-loader

註冊成功后,我們可以在 node_modules 目錄下能查找到對應的 loader。

3、在 webpack 中配置 loader

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

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

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

4、配置參數

上面我們是寫死的替換文案,假如我想通過配置項來改變,可以在 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,例如讀取輸出資源、代碼塊、模塊及依賴等;

1、編寫插件

在根目錄下,新建目錄 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

2、註冊模塊

按照以上的方法,我們在 my-plugin 目錄底下使用 npm link 做到在不發布模塊的情況下,將本地的一個正在開發的模塊的源碼鏈接到項目的 node_modules 目錄下,讓項目可以直接使用本地的 npm 模塊。

npm link

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

$ npm link my-plugin

註冊成功后,我們可以在 node_modules 目錄下能查找到對應的插件了。

3、配置插件

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

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

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

站長推薦

1.雲服務推薦: 國內主流雲服務商,各類雲產品的最新活動,優惠券領取。地址:阿里雲騰訊雲華為雲

2.廣告聯盟: 整理了目前主流的廣告聯盟平台,如果你有流量,可以作為參考選擇適合你的平台點擊進入

鏈接: http://www.fly63.com/article/detial/7647