天天看點

Webpack快速入門

Webpack快速入門

一、概述

webpack is a tool to build JavaScript modules in your application. webpack simplifies your workflow by quickly constructing a dependency graph of your application and bundling them in the right order. webpack can be configured to customise optimisations to your code, to split vendor/css/js code for production, run a development server that hot-reloads your code without page refresh and many such cool features.

webpack是一款前端資源子產品化管理和打包的工具。它可以将子產品按照依賴和規則進行打包,還可以将按需加載的子產品進行代碼分離,實作異步加載。通過加載器,任何形式的資源都可以被看作成子產品。

Github位址

從一個主檔案開始,依次尋找項目的所有依賴檔案,通過加載器進行處理,最後打包成浏覽器能夠識别的JavaScript檔案。

Webpack快速入門

二、特點

webpack和其他子產品化工具相比,具有如下特點:

  • 代碼分離

    webpack有兩種組織子產品依賴的方式:同步和異步。異步依賴會将代碼分離成不同的區塊,每一個區塊都作為一個檔案被打包。

  • 加載器

    webpack自身隻能處理原生的JavaScript子產品,通過加載器,可以将不同類型的資源轉換成JavaScript子產品。換句話說,任何資源都可以被webpack當成子產品來處理。

  • 智能解析

    webpack通過智能解析器,幾乎可以處理任何的第三方庫。并且在加載依賴的時候,允許使用動态表達式進行加載。

  • 插件

    webpack還提供了插件系統,大多數功能都是基于這個插件系統運作的。可以通過開發和使用webpack插件,滿足不同的需求。

  • 運作效率

    webpack通過異步I/O和多級緩存,大大提高了運作效率,能夠快速地實作增量編譯。

三、概念

為了能夠更好地了解和使用webpack,首先需要了解webpack的四大核心概念:

  • 入口entry

    webpack為應用程式的所有依賴建立了一個圖表,這個圖表的起始點被稱為入口點。入口點會告訴webpack從哪裡開始,并且根據依賴圖表,清楚哪些資源會被打包。

    entry

    屬性用來定義入口點。
  • 輸出output

    一旦将資源打包在一起之後,需要告訴webpack将要把應用程式打包到何處。

    output

    屬性用來描述打封包件的位置。
  • 加載器loaders

    當非JavaScript資源被添加到依賴圖表時,通過加載器将這些檔案轉換成子產品。

    test

    屬性用來定義要轉換的檔案類型。

    use

    屬性指定加載器的類型。
  • 插件plugins

    相對于加載器隻能基于每個檔案進行轉換,插件通常用來針對複雜應用執行操作和自定義功能。要想使用插件,首先需要使用require()方法引入插件子產品,然後在plugins數組中,建立一個該插件的執行個體。

四、安裝和配置

1、安裝Node.js

由于webpack需要使用npm進行安裝,是以應該首先安裝Node.js。

2、安裝webpack

通常不建議使用

$ npm install webpack -g

指令進行全局安裝。而是将webpack安裝到項目的依賴中,這樣,就可以使用項目本地版本的webpack。

進入到項目目錄,建立一個package.json檔案:

npm init
           

安裝webpack依賴:

npm install webpack --save-dev
           

也可以指定版本進行安裝:

npm install webpack@<version> --save-dev
           

如果需要使用webpack開發工具,需要單獨安裝:

$ npm install webpack-dev-server --save-dev
           

3、運作

如果采用非全局安裝,執行如下指令進行打包:

node_modules/.bin/webpack app/index.js public/bundle.js
           

其中,index.js是入口檔案,bundle.js是目标檔案。

4、配置

除了使用指令行運作webpack的方式,更好的方法是使用配置檔案

webpack.config.js

。它是一個node.js子產品,傳回一個json格式的配置資訊對象。也可以通過

--config

選項指定配置檔案。

module.exports = {
  entry: __dirname + "/app/index.js",
  output: {
    path: __dirname + "/public",
    filename: "bundle.js"
  }
}
           

其中,

entry

屬性指向入口檔案,

output

屬性指定打包後檔案存放的位置,

__dirname

指向目前執行腳本所在的目錄。

此時,執行

node_modules/.bin/webpack

指令,會自動參考配置檔案中的配置選項打包項目。

還有一種更快捷的運作方式。在package.json中設定npm的腳本:

"scripts": {
    "start": "webpack" // 将npm的start指令指向webpack指令
},
           

這樣,直接執行

npm start

指令,就會自動運作webpack進行打包。

五、用法

webpack很多強大的功能,都是通過一系列可供配置選項完成的。這裡主要介紹一些常用的選項。

1、開發工具devtool

開發工具主要用來友善調試,提高開發效率。通過打包之後的檔案,不太容易找到出現錯誤的地方對應的源碼位置。這時,可以使用Source Map來解決這個問題。

devtool: "source-map"
           

devtool

屬性有四種不同的選項值:

  • source-map,在一個單獨的檔案中産生一個完整且功能完全的檔案。這個檔案具有良好的source map,但會降低打封包件的建構速度。
  • cheap-module-source-map,在一個單獨的檔案中生成一個不帶列映射的map,能夠相應地提高建構速度,但不能對應到具體的列,會對調試造成不便。
  • eval-source-map,使用eval打包源檔案子產品,在同一個檔案中生成幹淨且完整的source map,不會影響建構速度,但輸出的js檔案存在性能和安全隐患。建議在開發階段使用,一定不要在生産階段使用此選項。
  • cheap-module-eval-source-map,能夠以最快的速度生成source map,生成的source map和打包後的js檔案同行顯示,沒有列映射。同樣建議隻在開發階段使用。

Tips:在開發階段使用eval-source-map選項。

2、本地伺服器devserver

開發過程中,希望浏覽器能夠監測到代碼的修改,并自動重新整理,顯示修改之後的結果。這時,可以配置devserver建構本地伺服器來完成這些功能。

devServer: {
    contentBase: "./public",
    inline: true,
    colors: true,
    historyApiFallback: true
}
           

因為本地伺服器是一個單獨元件,是以在配置之前需要單獨安裝:

npm install webpack-dev-server --save-dev
           

devserver

屬性有如下配置選項:

  • contentBase,預設情況下,為根檔案夾提供本地伺服器。如果想為其他目錄提供本地伺服器,可以在此選項設定目錄。
  • port,設定監聽端口,預設為8080。
  • inline,設定為true時,當源檔案發生改變會自動重新整理頁面。
  • colors,設定為true時,終端輸出的結果為彩色的。
  • historyApiFallback,設定為true時,所有的跳轉都指向index.html,主要用于單頁面應用。

3、加載器loaders

Loaders是webpack最強大的功能之一。通過使用不同的loader,webpack調用外部的腳本或工具,可以對各種格式的檔案進行處理。

Loaders需要單獨安裝:

npm install json-loader --save-dev
           

并且需要在

modules

屬性下進行配置:

module: {
    loaders: [
      {
        test: /.json$/,
        loader: "json"
      }
    ]
}
           

loaders

屬性有如下配置選項:

  • test,比對loaders所處理檔案的擴充名的正規表達式(必須)。
  • loader,loader的名稱(必須)。
  • include,添加必須處理的檔案夾或檔案(可選)。
  • exclude,屏蔽不需要處理的檔案夾或檔案(可選)。
  • query,為loaders提供額外的設定選項(可選)。

webpack提供了很多有用的loader,如css-loader和style-loader,用來處理樣式表。css-loader能夠使用類似@import和url()的方法實作require()的功能,而style-loader則将所有計算後的樣式加到頁面中。

安裝:

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

配置:

module: {
    loaders: [
      {
        test: /.css$/,
        loader: "style!css"
      }
    ]
}
           

其中,“!"表示同一檔案能夠使用不同類型的loader。

Sass或Less之類的預處理器是對原生CSS的拓展,不同類型的預處理器也對應不同的loader。webpack還提供一個CSS處理平台PostCSS,可以使CSS能夠實作更多功能。使用PostCSS可以為CSS代碼自動添加适應不同浏覽器的CSS字首。

安裝:

npm install postcss-loader autoprefixer --save-dev
           

配置:

postcss: [
    require('autoprefixer')
]
           

Babel是一個編譯JavaScript的平台,它支援下一代的JavaScript标準(如:ES6),以及基于JavaScript進行拓展的語言(如:JSX)。

安裝:

npm install babel-core babel-loader babel-preset-es2015 --save-dev
           

配置:

module: {
    loaders: [
      {
        test: /.js$/,
        exclude: /node_modules/,
        loader: "babel",
        query: {
          presets: ['es2015']
        }
      }
    ]
}
           

4、插件plugins

webpack的另一個強大功能。在整個建構過程中,執行相關任務,拓展webpack功能。webpack有很多内置插件,同時也有很多第三方插件。

要想使用插件,首先需要安裝:

npm install html-webpack-plugin --save-dev
           

然後在

plugins

屬性中添加該插件的一個執行個體:

plugins: [
    new HtmlWebpackPlugin({
        template: __dirname + "/app/index.tmpl.html"
    })
]
           

Hot Module Replacement(HMR)也是webpack中很實用的插件,允許在修改元件代碼後,自動重新整理實時預覽修改後的效果。

實作HMR隻需要進行如下幾項配置。

在plugins中添加HMR插件:

new webpack.HotModuleReplacementPlugin()
           

在devserver中添加hot屬性:

hot: true
           

在js子產品中執行webpack提供的API。

5、産品建構

雖然以上内容可以建構一個完整的開發環境,但在産品階段,可能還需要對打包的檔案進行額外的處理,如:優化、壓縮、緩存、代碼分離等。

  • OccurenceOrderPlugin,為元件配置設定ID,webpack可以分析和優先考慮使用最多的子產品,并為其配置設定最小的ID。
  • UglifyJsPlugin,壓縮js代碼
  • ExtractTextPlugin,分離css和js檔案

使用緩存最好的方法是保證檔案名和檔案内容相比對。webpack可以把一個哈希值添加到打包的檔案名中。

output: {
    path: __dirname + "/build",
    filename: "[name]-[hash].js"
}
           

參考文章:

入門Webpack