Webpack坑位之輸出

webpack之輸出

webpack的最後就是爲了獲得打包結果。css

那這是一個怎麼樣的過程,不一樣的配置,會有什麼樣的結果呢?html

本文的原文在個人博客中:github.com/RachelRen/b…,歡迎star。node

首先從最簡單的配置開始output。告訴webpack在哪裏打包應用程序。webpack

output: {
	    path: path.resolve(__dirname, 'build'),
	    filename: 'js/[name].js',
	    publicPath: '/',
	    chunkFilename:'js/[name].chunk.js',
		//chunkFilename:'js/[name].[chunkhash:8].chunk.js',
	},

複製代碼

在這裏能夠看到不少類似,可是有不一樣含義的名次,如filenamechunkFilenamehashchunkhash,那他們有什麼區別呢?git

而這裏的chunk又是什麼意思呢?github

chunkFilename VS filename

webpack 將多個模塊打包以後的代碼集合稱爲 chunk。 這兩個的區別:chunkFilename 是無入口的chunk在輸出時的文件名稱。chunkFilename只用於在指定在運行過程當中生成的chunk在輸出時的文件名稱。web

但在webpack4以上的時候,發如今entry中配置的入口文件,打包的結果是index.chunckfile.js,屬於chunkFilename,由於設置了promise

optimization: {
    splitChunks: {
      	chunks: 'all',
     	name: 'common',
    },
    runtimeChunk: { 
     	name: 'runtime',
    }
},
複製代碼

當去掉runtimeChunk這個配置時,那麼入口文件,又會變成filename。主要緣由是bash

經過設置 optimization.splitChunks.chunks: "all" 來啓動默認的代碼分割配置項。經過知足下面的條件,webpack會自動打包chunkside

  • 當前模塊是公共模塊(多處引用)或者模塊來自 node_modules
  • 當前模塊大小大於 30kb
  • 若是此模塊是按需加載,並行請求的最大數量小於等於 5
  • 若是此模塊在初始頁面加載,並行請求的最大數量小於等於 3

optimization.runtimeChunk

經過設置 optimization.runtimeChunk: true 來爲每個入口默認添加一個只包含 runtime 的 chunk(webpack會添加一個只包含運行時(runtime)額外代碼塊到每個入口)。

chunkhash VS hash

output: {
	filename: 'js/[name].[chunkhash:8].js',
	path: path.join(__dirname, './build'),
    publicPath: '/',
    chunkFilename:'js/[name].[chunkhash:8].chunk.js',
},
複製代碼

在webpack 4這樣打包的話,會報錯。

ERROR in chunk runtime [entry]
js/[name].[chunkhash:8].js
Cannot use [chunkhash] or [contenthash] for chunk in 'js/[name].[chunkhash:8].js' (use [hash] instead)
複製代碼

因此就想搞明白這兩個的區別究竟是什麼。

chunkhash

[chunkhash] is replaced by the hash of the chunk.

chunkhash表明的是chunk的hash值。chunk在webpack中的就是模塊的意思,那麼chunkhash就是根據模塊內容計算得出的hash值。

hash

[hash] is replaced by the hash of the compilation.

hash 是compilation的hash值。

compilation對象表明某個版本的資源對應的編譯進程。在使用webpack的development中間件時,每次檢測到項目文件有變更時會建立一個compilation,因此可以針對改動生成全新的編譯文件。compilation對象包含當前模塊資源,編譯文件,有改動的文件盒監聽依賴的全部信息。

compiler和compilation的區別是。 compiler是配置完備的webpack環境。compiler只在webpack啓動時構建一次,由webpack組合全部的配置構建生成。compiler是不變的webpack環境,是針對webpack的。而compilation是針對隨時可變的項目文件,只要有文件改動,compilation就會被從新建立。

compilation在項目中任何一個文件改動後就會被從新建立,而後webpack計算新的compilation的hash值,這個hash值即是hash。

hash是compilation對象(所用compilation對象?)計算所得,而不是具體的項目文件計算所得。因此以上配置的編譯輸出文件,全部的文件名都會使用相同的hash指紋。

chunkhash是根據具體模塊文件的內容計算所得的hash值,因此某個文件的改動只會影響它自己的hash指紋,不會影響其餘文件

hash的應用場景

接上文所述,webpack的hash字段是根據每次編譯compilation的內容計算所得,也能夠理解爲項目整體文件的hash值,而不是針對每一個具體文件的。

因此若是用optimization.splitChunks.runtimeChunk生成的文件,就是以hash做爲文件後綴的runtime.[hash].js,並且每次文件修改,都會生成一個新的文件。

hash是跟整個項目的構建相關,只要項目裏有文件更改,整個項目構建的hash值都會更改,而且所有文件都共用相同的hash值

總之一句話: hash是總體的文件計算所得,chunkhash是具體模塊文件所得。

代碼分離

如今不少系統都是SPA,當發展愈來愈龐大的時候,js的拆分就愈來愈重要的。那麼怎麼拆分js就很重要了。

分離主要有三種方式:

  1. 入口起點:使用 entry 配置手動地分離代碼。
  2. 防止重複:使用 SplitChunksPlugin 去重和分離 chunk。
  3. 動態導入:經過模塊中的內聯函數調用來分離代碼。

入口起點

這種方式是最簡單,最直觀的方式。可是有一些他的缺點:

  1. 若是入口 chunk 之間包含一些重複的模塊,那些重複模塊都會被引入到各個 bundle 中。
  2. 這種方法不夠靈活,而且不能動態地將核心應用程序邏輯中的代碼拆分出來。

防止重複

SplitChunksPlugin 插件能夠將公共的依賴模塊提取到已有的 entry chunk 中,或者提取到一個新生成的 chunk。在webpack 4.0 以前是用CommonsChunkPlugin來作代碼分離的

plugins: [
  new webpack.optimize.CommonsChunkPlugin({
    names: ['vendor', 'manifest']
  })
]
複製代碼

在webpack 4.0以後,就經過optimization.splitChunks來分離代碼了。

optimization: {
    splitChunks: {
       chunks: 'all'
    }
}

複製代碼

動態導入

若是系統很龐大,將代碼一次性載入,就顯得太過於強大,最好能作到根據咱們的需求來選擇性地加載咱們須要的代碼。

webpack 提供了2種方式來拆分代碼。

  1. 符合 ECMAScript 提案 的 import() 語法 來實現動態導入。(import() 調用會在內部用到 promises。)
  2. 則是 webpack 的遺留功能,使用 webpack 特定的 require.ensure

Public Path vs Path

在配置過程當中,也會遇到這兩個概念。

publicPath: 用來爲項目中的全部資源指定一個基礎路徑。使用的是相對路徑。

filename:'[name]_[chunkhash:8].js'
publicPath: 'https://cdn.example.com/assets/'
複製代碼

那麼發佈上線的時候,路徑就是:

<script src='https://cdn.example.com/assets/a_12345678.js'></script>
複製代碼

靜態資源最終訪問路徑 = output.publicPath + 資源loader或插件等配置路徑

path: 配置輸出文件存放在本地的目錄,必須是 string 類型的絕對路徑,一般經過 Node.js 的 path 模塊去獲取絕對路徑:

path: path.resolve(__dirname, 'dist_[hash]')

複製代碼

Webpack中hash與chunkhash的區別,以及js與css的hash指紋解耦方案

腦闊疼的webpack按需加載

代碼分離

相關文章
相關標籤/搜索