Webpack上手指北

近幾年,打包構建工具層出不窮,前有Grunt、Gulp,後有Webpack、Rollup等,它們各有優點,均受到部分開發者的歡迎,本文聊聊Webpack的使用。css

模塊化

不管是新工具仍是新技術,都是爲了解決問題而存在,那麼構建工具解決什麼問題呢?html

衆所周知,最初的網頁十分簡單,沒有多少交互,代碼量也少,但隨着技術的發展,JavaScript已經不只僅用來實現簡單的表單提交等功能,引入多個js文件到頁面中成爲常態,但這種作法有不少缺點:前端

1)須要手動維護文件的加載順序。且多個js之間一般有依賴關係,難以清晰分辨誰依賴了誰。vue

2)每個<script>標籤都須要向服務器發送請求,過多的請求會嚴重拖慢渲染速度。node

3)每一個<script>標籤都暴露在全局做用域,若是沒有任何處理而直接在代碼中進行變量或函數聲明,就會形成全局污染。webpack

模塊化解決了這些問題:web

  • 經過分離模塊,導入和導出,能夠清晰地看到模塊間的依賴關係。npm

  • 藉助工具進行打包,頁面中只須要加載合併後的資源文件,減小了網絡開銷。json

  • 模塊之間做用域隔離,彼此不會有命名衝突。數組

使用Webpack的理由

打包工具衆多,爲何選擇Webpack?Webpack具有如下幾點優點。

1)默認支持多種模塊標準,包括AMD、CommonJS,以及最新的ES6模塊。這對於某些同時使用多種模塊標準的工程很是有用,Webpack會幫咱們處理好不一樣類型模塊之間的依賴關係。

2)完備的代碼分割解決方案。能夠分割打包後的資源,首屏只加載必要的部分,不重要的放到後面動態加載。這對於體積較大的應用尤其重要,可有效減少資源體積,提高首頁渲染速度。

3)能夠處理各類類型的資源。除JavaScript之外,還能夠處理樣式、模板、圖片等,而開發者須要作的僅僅是導入它們。好比你能夠從JavaScript文件導入一個CSS或者PNG,而這一切最終均可以由下面講到的loader來處理。

4)龐大的社區支持。除了Webpack核心庫之外,還有無數開發者爲它編寫周邊插件和工具,大多數的需求你均可以找到現有解決方案。

配置與方法

看看怎麼使用。

依賴Node,這幾乎是前端開發的標配,很少說。

學習一種東西的時候最怕看到各類陌生概念,這裏先捋一捋。

爲了便於理解,按照工做流程的階段:

entry:流程的入口,告訴webpack從哪一個文件開始打包,方式包括:字符串、對象、函數等。

字符串寫法

const config = {
  entry: './entry/file.js'
};

module.exports = config;
複製代碼

對象寫法

const config = {
  entry: {
    app: './src/app.js',
    vendors: './src/vendors.js' //第三方庫入口
  }
};
複製代碼

多頁面

const config = {
  entry: {
    pageOne: './src/pageOne/index.js',
    pageTwo: './src/pageTwo/index.js',
    pageThree: './src/pageThree/index.js'
  }
};
複製代碼

至於函數的方式,能夠有邏輯處理的發揮空間,最終返回的仍是字符串或者對象。

chunk:字面意思是代碼塊,存在依賴關係的模塊在打包時被封裝爲一個chunk bundle:由chunk獲得的打包產物

因此三者的關係如圖:

先消除一個可能的誤解,並不是是一個entry項對應一個chunk,對應一個bundle,均可能是多個,後面會再說。

output:設置輸出路徑和文件

單入口

const config = {
  output: {
    filename: 'bundle.js',
    path: '/public/assets'
  }
};

module.exports = config;
複製代碼

多入口

{
  entry: {
    app: './src/app.js',
    about: './src/about.js'
  },
  output: {
    filename: '[name].js',
    path: __dirname + '/dist'
  }
}
複製代碼

這裏就遇到了上面提到的」多對多「的關係。

其中filename是輸出資源文件名,不只能夠是名稱,還能夠是相對路徑,並且目錄不存在也不要緊,會自動建立。

能夠看到,filename 使用了[name],這是由於多個文件須要生成多個對應的文件,[name]相似模板語言,意圖是根據入口文件動態生成文件名,以確保惟一性。

固然,[name]只是模板變量之一,還有能夠控制客戶端緩存的[hash][chunkhash]等,能夠精確地讓相應文件在客戶端獲得更新。就像這樣

output:{
  filename:'[name]@[hash].js'
}
複製代碼

loader:字面意思是裝載器,能夠理解爲」預處理器「,Webpack自己只認識JavaScript,對其餘類型,好比:樣式、圖片等,必須預約義一個或多個loader對其進行轉譯,因此loader賦予webpack處理不一樣資源的能力,豐富了擴展性。

用法示例以下:

首先說明,loader不是webpack自帶的,須要安裝,好比咱們處理樣式。

npm install --save-dev css-loader style-loader

module: {
    rules: [
      {
        test: /\.css$/,
        use: ['style-loader','css-loader']     
      }
    ]
  }
複製代碼

能夠看出,loader的套路很簡單:

  1. 文件類型
  2. 對應loader

須要說明的是:

  1. css-loader 自己僅處理樣式的加載,並不負責將樣式插入頁面,因此一般配合 style-loader 一塊兒使用,預處理器一樣。
  2. use數組當中的loader順序是有講究的,它是從後往前進行處理,搞錯了順序一樣沒法達到想要的效果。

plugin: loader是作某些類型文件的模塊轉換工做,相比之下,plugin是用來完成一些loader職責以外的任務,更多,更豐富,也加強了webpack的能力。

用法以下:

plugins: [
    new HtmlWebpackPlugin({template: './src/index.html'})
]
複製代碼

它的可配置項有不少,這裏再也不列舉,只要知道它是一個具備 apply 屬性的 JavaScript ,能夠攜帶參數,因此要向plugin屬性傳入 new 實例。

配置文件

說到這兒,你可能以爲都是零散的概念,它們應該放在哪兒?

有一種」最佳實踐「叫配置分離,即配置文件單獨放在一個文件當中,node有package.json,webpack也有,咱們上面提到的全部,都應該寫在一個叫webpack.config.js的文件當中。譬如:

//webpack.config.js
var path = require('path');

module.exports = {
  mode: 'development',  //模式,分爲 development 和 production
  entry: './index.js',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'index.bundle.js'
  },
  module: {
    rules: [
      {
        test: /\.css$/,
        use: ['style-loader','css-loader']     
      }
    ]
  },
  plugins: [
    new HtmlWebpackPlugin({template: './src/index.html'})
  ]
};
複製代碼

最基本的配置就是這樣了,若是看作是一條生產線的話,就是從入口文件進,從dist輸出。

實際開發中會加入更多邏輯和工具,代碼量會大大增長,但使用方法相似。

更多配置

經常使用loader

說到這兒,你可能會問,我知道webpack拿loader做爲工具,但有哪些工具可用呢?下面介紹幾個:

  • babel-loader

用途你們都很熟,把ES6+代碼編譯爲ES5,可讓你們在瀏覽器支持度不是很充分的狀況下用新方法編碼。

推薦安裝:babel-loader @babel/core @babel/preset-env

  • ts-loader

用於鏈接Webpack和Typescript。

  • html-loader

前面說過,Webpack只認識js,這個loader用於將HTML文件轉化爲字符串並格式化,經過js加載。

  • file-loader

打包文件類型資源,返回publicPath。 對publicPath稍做解釋,前面咱們看到過path,它是資源打包路徑,而publicPath是資源引用路徑,即頁面當中作引用的靜態文件(圖片等)。

  • vue-loader

這個應該不少人在用,處理vue組件,除此以外,可能還要安裝vue-template-compiler以及前面提到的樣式處理loader等。

更多loader

經常使用插件

  • html-webpack-plugin

自動生成html文件,而且引用相關的 assets 文件。

  • mini-css-extract-plugin

分離CSS,將CSS提取到單獨的文件中,支持CSS和sourceMap的按需加載。

  • uglifyjs-webpack-plugin

對js進行壓縮混淆。

  • Hot Module Replacement

瀏覽器自動更新,實時預覽修改效果

  • CommonsChunkPlugin/SplitChunks

把多個chunk中的公共部分提取出來,減小重複打包,縮小資源說起,能夠更有效利用客戶端緩存。

更多插件

總結

文章已經有點長,但仍有不少東西沒有講到,沒有深刻,旨在跟你們分享webpack的用途以及大體用法,更詳細內容及工具可移步官網查看。

但對於創建初步的認識應該足夠,剩下的,各公司或者業務的特色都不同,你們可根據具體狀況進行定製,總之,工具是爲我所用的,是爲開發者提供便利的,而不是攔路虎,應該學會並掌握它。

下篇見!~

Webpack上手指北

相關文章
相關標籤/搜索