Webpack飛行手冊

来源:http://www.cnblogs.com/jinma/archive/2017/12/07/Web.html
-Advertisement-
Play Games

Webpack 是一款目前非常流行的前端模塊打包工具,可以將項目中所載入的模塊進行打包,以及將 一些瀏覽器不支持的語言進行轉換。 ...


前言

在學習 Webpack 之前,我們需要瞭解一個概念:模塊

何為模塊?

如果你曾學過 Java , C# 之類的語言,一定會知道 Java 中的 import 或 C# 中的 using 吧?

比如:我想在 C# 中進行資料庫操作,我只需要在代碼頭部加上 下麵這兩段代碼即可。

using System.Data;
using System.Data.SqlClient;

這兩段代碼可以看成 兩個與資料庫操作相關的模塊。
當我們需求是資料庫,或者是讀取 IO 等其他操作,我們便載入其他不同的模塊。

很明顯,這實現了編程中的一個非常重要的功能 按需載入

在前端中 模塊又該如何定義呢?
按照我個人的理解:

  • 在 HTML 中 模塊 便是一個組件

    <div class="layer">
    <div><%= name %></div>
    <% for(var i = 0; i < People.length;++i) { %>
        <%= People[i] %>
    <% } %>
    </div>
  • 在 CSS 中 模塊 便是一個局部樣式

    header{
    display:block;
    }
    header h1{
    font-size: 60px;
    }
  • 在 Javascript 中 模塊 便是一個封裝著方法或數據的腳本文件

    let People = { name: "Simon" } ;
    module.exports = People;

而我們又該怎樣實現 在前端中載入模塊呢?

下麵是兩個很常見的例子:

在 Less 中

@import "header";
@import "layout";
@import "footer";

在 Javascript

// CommonJS
const $ = require("jQuery");

//es6
let People = { name: "Simon" } ;
module.exports = People;

import "./layer.less";
import tpl from "./layer.ejs";

如果你直接運行以上代碼,瀏覽器並不會解析,這個時候,就要依靠 Webpack 了!

Webpack是什麼

Webpack 是一款目前非常流行的前端模塊打包工具,可以將項目中所載入的模塊進行打包,以及將 一些瀏覽器不支持的語言進行轉換。

Webpack 的打包原理是 先找到入口文件,遞歸探索出所有依賴的模塊,最後 利用 Loader 進行不同文件類型的處理,打包成一個 Javascript 文件。

其中,Webpack 的兩個最核心原理分別是:

  1. 一切皆模塊
  2. 按需載入

當然 Webpack 的作用不止載入模塊這麼簡單,前端的常用需求通常都可以實現:利用 Loader 轉換 es6 、 Less 、 Typescript ,還可利用插件 開發多頁面應用,等等諸多強大功能。

正文

下麵,我將講解 Webpack 的具體使用和配置。

安裝

我一般在項目中使用 Webpack,都是先執行下麵這四條命令進行 Webpack 的安裝

  1. npm install -g webpack

    在全局安裝 Webpack,第一次使用時 執行
  2. npm install --save-dev webpack

    將 Webpack 安裝到你的項目
  3. npm init

    npm初始化,會詢問你的項目信息,可以回車跳過
  4. npm install --save-dev webpack-dev-server

    在當前項目,安裝 Webpack 伺服器

安裝完成後,便是建立配置文件了。

基本配置

在項目根目錄下新建名為 webpack.config.js 的文件,

基本上 一個配置文件的大體結構就是下麵這樣:

modules.export={
    entry:{
        /* 入口文件 */
    },
    output:{
        /* 出口文件 */
    },
    module:{
        /* Loader */
        rules:[{},{},{}]
    },
    plugins:[ 
        /* 插件 */ 
    ],
    devtool: ...
    devServer: {...}
    resolve:{...}
}

我們下麵就先分析 modules.export 各個屬性

入口

entry
代表是入口文件,Webpack 工作的開始。

Webpack 會遞歸的探索出 入口文件中所依賴的模塊,並按照順序 利用 Loader 進行處理。

官網給出了其 3 種數據類型:

  1. 字元串

    entry: "app.js";
  2. 數組

    數組中的每一項都會被打包,形成互不依賴的文件

    entry: ["app.js","main.js"];
  3. 對象

    對象中的每一個屬性都會被打包,形成互不依賴的文件

    entry:{
        app: "./src/js/app.js",
        main: "./src/js/main.js"
    }

    一般入口文件中多是 import 或者 require 等模塊導入命令。

出口

output
顧名思義,Webpack打包後文件的具體配置
常用的屬性有 4 個

  1. path: ${__dirname }/dist

    打包後文件所在路徑
  2. filename: "js/[name].js"

    打包後文件的名字,這裡有 4 種常用的寫法
    1. 自定義
    2. [name].js

      代表的便是入口的文件名
    3. [hash].js

      此次打包後的hash值
    4. [chunkhash]

      該塊打包後的hash值

  3. publicPath: "http://cdn.com/"

    上線時的公共路徑,主要應用於線上
  4. chunkFilename: 'js/[name].js'

    按需載入模塊時輸出的文件名稱

Loader

Loader 是 Webpack 中最振奮人心的東西了!

將一切瀏覽器不支持的語言,處理成 瀏覽器可以支持。
針對各個文件類型,都有各種的 Loader 等你去挖掘。

Loader 的工作方式 是從右向左執行,鏈式地按照順序進行編譯。
loader 鏈中的第一個返回值給下一個 loader,在最後一個 loader,返回所預期的結果。

loader 可以是同步或非同步函數,也可使用 options 對象去接受配置參數。

基礎結構

module:{
    rules:[
        {
            test:/\.xxx$/,//以xxx結尾的文件
            loader: "xxx-loader",
            exclude: {排除的路徑},
            include: {包含的路徑},
            options: {Loader配置}
        }
    ]
}

可以很清楚的看到,Loader 利用 test 的正則 找到各個類型文件,然後使用 loader 進行處理,便可轉換成瀏覽器支持的文件。

其中我知道的 loader 的寫法有兩種:

  1. 每一個 loader 都是一個對象

    loaders:[
    {loader:"style-loader"},
    { loader: "css-loader?modules", options: { importLoaders: 1 } },
    {loader: "less-loader"}
    ]
  2. 使用 ! 號拼接的寫法

    loader: "style-loader!css-loader?importLoaders=1!less-loader"

    下麵介紹三個 前端必備的 Loader 方式

    css

  3. style-loader

    通過註入<style>標簽將 CSS 添加到 DOM

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

    css-loader像import / require()一樣解釋@import和url()並解析它們。

    npm install css-loader --save-dev
  5. postcss-loader

    補充 不相容的css屬性 的瀏覽器首碼

    npm install post-loader --save-dev
  6. less-loader

    將Less 轉換成 CSS

    npm install less --save-dev
    npm install less-loader --save-dev

javascript

babel

主要用於將 es6 轉換成 es2015
npm install --save-dev babel-core babel-loader babel-preset-es2015

圖片 & 字體

  1. file-loader

    用於壓縮文件

    npm install --save-dev file-loader
  2. url-loader

    如果文件下於 規定限制,將會轉換成 二進位編碼

    npm install --save-dev url-loader

    ejs

    另外 我想介紹一下 自己常用的 ejs-loader
  3. 配置

    npm install --save-dev ejs-loader
    test:/\.ejs$/ , loader:"ejs-loader",
  4. 使用

<div class="layer">
    <div><%= name %></div>
    <% for(let i = 0; i < Array.length;++i) { %>
        <%= Array[i] %>
    <% } %>
</div>
//入口文件
import tpl from "./layer.ejs";

document.body.innerHTML = tpl({
    name:"Simon",
    arr:["Apple","Xiaomi"]
});

運行 生成後的頁面 ,便會發現 ejs 組件已經被加進去了,
想象一下,我們在平時工作中是否可以把 一個輪播圖,或者 排行榜 、評論 當成一個組件呢?

插件

plugins

在日常工作中,我們使用 Loader 處理不同類型的文件,當有某種其他方面的需求時,比如 抽離 CSS 、生成多頁面 HTML ,plugins 便派上了用場。

插件的使用,一般都要先 require 出來,然後在 plugins 屬性中 進行初始化

const htmlWebpackPlugin = require("html-webpack-plugin");
......
plugins: [ new htmlWebpackPlugin({/* options */}) ]

下麵將介紹 一些工作中常用的插件

  1. clean-webpack-plugin

    主要用於 打包之前 先清空 打包目錄下的文件,防止文件混亂。

    npm install --save-dev clean-webpack-plugin 
  2. html-webpack-plugin

    主要用於生成HTML,可以規定 模板HTML,也可以為 模板傳入參數,壓縮文件等

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

    這個插件可謂是 前端必備的,它的配置有很多
    ```jsx

new htmlWebpackPlugin({
//打包後的文件名
filename: "index.html",

//模板
template: "index.html",

//為true自動生成script標簽添加到html中
//或者寫 body/head 標簽名
inject: false,//js的註入標簽

//通過<%= htmlWebpackPlugin.options.title %>引用
title: "參數title",

//通過<%= htmlWebpackPlugin.options.date %> 引用
date: new Date()

//網站的圖標
favicon: 'path/to/yourfile.ico'

//生成此次打包的hash
//如果文件名中有哈希,便代表有 合理的緩衝
hash: true,

//排除的塊
excludeChunks: [''],

//選中的塊 與入口文件相關
chunks: ['app','people'],

//壓縮
minify:{
removeComments: true,collapseWhitespace: true,
minifyJS: true, minifyCSS: true,minifyURLs: true,
}

}),
那麼問題來了,我們在模板文件中 又該怎樣使用參數呢? 直接按照 ejs 的語法寫入 html 文件即可!html


<%= htmlWeb
packPlugin.options.date %>

```

生成後的模板文件

<!DOCTYPE html>
<html lang="en">
Thu Dec 07 2017 10:01:58 GMT+0800 (中國標準時間)
</html>

另外,如果想生成 多頁面應用,只需 將上面的配置,多複製幾遍即可。

new htmlWebpackPlugin({ filename: "index1.html", }
new htmlWebpackPlugin({ filename: "index2.html", }
new htmlWebpackPlugin({ filename: "index3.html", }
  1. UglifyJsPlugin

    主要用於壓縮 Javascript 文件

    npm i -D uglifyjs-webpack-plugin
  2. webpack.ProvidePlugin

    自動載入模塊,全局使用變數,下麵藉助 官網的DEMO

    new webpack.ProvidePlugin({
      $: 'jquery',
      jQuery: 'jquery'
    })
    // in a module
    $('#item'); // <= 起作用
    jQuery('#item'); // <= 起作用
    // $ 自動被設置為 "jquery" 輸出的內容
  3. open-browser-webpack-plugin

    打開伺服器後 會自動打開瀏覽器埠,用起來 很方便
  4. HotModuleReplacementPlugin

    熱更新插件

常用命令

  • webpack

    最基本的啟動webpack命令

  • webpack -w

    監控代碼變化,實時進行打包更新
  • webpack -p

    對打包後的文件進行壓縮,利用線上發佈
  • webpack -d

    提供SourceMaps,方便調試代碼
  • webpack --colors

    輸出結果帶彩色,可以更詳細的查看信息
  • webpack --profile

    輸出性能數據,可以看到每一步的耗時

devtool

不知道你現在時候有沒有一個想法? webpack 打包後的文件就一定正確無誤嗎? 如果發生錯誤的話,該怎麼辦呢?

devtool 屬性 便提供了生成 sourcemap 的功能,具體有下麵這些選項。

  1. source-map

    此選項具有最完備的source map,但會減慢打包的速度;
  2. cheap-module-source-map

    生成一個不帶列映射的map
  3. eval-source-map

    使用eval打包源文件模塊,生成一個完整的source map。
  4. cheap-module-eval-source-map

    這是最快生成source map的方法,生成後的Source Map 會和打包後的 JavaScript 文件同行顯示,但沒有列映射,所以慎用

devServer

  1. contentBase: "./dist",

    本地伺服器所載入的頁面所在的目錄
  2. historyApiFallback: true,

    再找不到文件的時候預設指向index.html
  3. inline: true,

    當源文件改變時會自動刷新頁面
  4. hot: true,

    熱載入開啟
  5. port:8080

    設置預設監聽埠

resolve

  1. extensions: [".js", ".html", ".css", ".txt","less","ejs","json"],

    自動擴展文件尾碼名,意味著我們require模塊可以省略不寫尾碼名

  2. alias: { Temp: path.resolve(__dirname, "src/templates/") }

    模塊別名定義,直接 require('AppStore') 即可,方便後續直接引用別名

其他功能

path

常用於字元串拼接路徑。

const path = require("path");

有兩個 API

  1. path.resolve()

將相對路徑轉換成絕對路徑

const aPath = path.resolve("__dirname","js","main.js");
// aPath = 當前目錄下的 js 文件夾的 main.js 文件的路徑
  1. path.join()

對路徑進行拼接

const rPath = path.join("source","js","main.js");
// aPath = //source/js/main.js
  1. __dirname
    Node.js 中的全局變數,代表的是 項目的當前路徑。常與 path 結合使用。

熱更新

上面我們已經提過了 webpack -w 命令,它可以實時的監控 代碼的改變,從而自動進行打包,但是 有個缺點 在於它不能及時的刷新界面。

在我們 開啟伺服器後,是無法使用 此命令的,這個時候,如果你還想進行 自動打包,又想自動刷新界面,熱更新 便是不二之選,另外 Webpack 只會熱更新 發生改變的模塊,不會重新載入整個頁面,便可加快開發速度。

開啟步驟:

  1. 修改 devServer屬性

    devServer: {
    hot: true,//熱載入開啟
    inline: true,//文件改變時會自動刷新頁面
    }
  2. 增加熱更新插件
    ```jsx
    const webpack = require("webpack");
    //Other property
    plugins: [
    new webpack.HotModuleReplacementPlugin()]

```
另外,只有修改 依賴的項目,才會進行實時更新。

結束語

現在是一個 Web 技術蓬髮的時代,一定要把握住時代潮流。

在寫這篇文章前,我已經花了一整天的時間,把工作所需要 幾乎所有的 Loader , plugins 收集了一遍,專門寫了個源文件。但因為我的源文件太大 必須可顯示,可隱藏,不然影響閱讀 ,可博客園的 Markdown 不支持自定義樣式 ,所以我貼在了我的博客,希望它能對你有幫助。

另外,再送你個福利,如果你是個人博客愛好者,我最近新開發了一款美觀開源的主題,等待你的使用。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 對於剛開始學習js的同學,強烈推薦直接使用chrome developer mode,超級方便。 隨便打開一個網頁,開啟開發者模式即可寫js代碼,不用新建html和js文件即可看到自己寫的js代碼的結果 如下: 甚至連console.log();都可以不用就能看到輸出結果,是不是很方便。 開啟開發者 ...
  • <html><head> <meta charset="utf-8"> <title>Swiper輪播</title></head><body> <div class="swiper-container" id="Exhibition-swiper" style="width:800px"> <di ...
  • 這是繼前兩篇後的第三篇,這一章主要是說關於react裡面樣式的一些問題,這樣讓你頁面構建更加美觀。 ...
  • 一般元素在頁面所占的空間包括:magin border padding content。以前一直以為子元素設置百分比寬高都是以父元素的content值為基準計算的。但是當子元素的position不同時,卻是不同的結果。 demo 用如下小demo測試: 效果如下: 子元素以父元素的content寬度 ...
  • $("#ZB").attr("ondrawsummarycell", "ondrawsummarycell"); // ZBMX需要替換為子表對應控制項的控制項編號 彙總數據 $("#ZB").attr("ondrawcell", "ondrawcell"); // ZBMX需要替換為子表對應控制項的控制項... ...
  • git是什麼 簡單來說,Git,它是一個快速的 分散式版本控制系統 。 同傳統的 集中式版本控制系統 不同,Git的分散式特性使得開發者間的協作變得更加靈活多樣。 這時候我們會想到: 1. 什麼又是版本控制呢? 2. 什麼是分散式什麼是集中式? 我們帶著問題往下走。 版本控制 版本控制是一種記錄一個 ...
  • 變數、嵌套、混合(mixin)、繼承拓展、@import、comment 變數的意義 在sass里我們可以定義多個變數來存放顏色、邊框等等的樣式,這樣就可以在下麵想要使用樣式的時候使用變數了 這樣的優點就是便於維護,更改方便 變數的使用 可以通過$來定義變數,在變數名字中可以使用 和_來作為連接,並 ...
  • 1.安裝sass 1.安裝ruby 因為sass是用ruby語言寫的,所以需要安裝ruby環境 打開安裝包去安裝ruby,記住要勾選 下麵選項來配置環境路徑 [x] Add Ruby executables to your PATH 安裝完成之後繼續下一步操作 2.安裝sass 在cmd里通過gem ...
一周排行
    -Advertisement-
    Play Games
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...