webpack 四個(gè)核心概念

webpack 是當(dāng)下最熱門的前端資源模塊化和打包工具。它可以將許多松散的模塊(如 CommonJs 模塊、 AMD 模塊、 ES6 模塊、CSS、圖片、 JSON、Coffeescript、 LESS 等)按照依賴和規(guī)則打包成符合生產(chǎn)環(huán)境部署的前端資源。當(dāng) webpack 處理應(yīng)用程序時(shí),它會(huì)遞歸地構(gòu)建一個(gè)依賴關(guān)系圖表,其中包含應(yīng)用程序需要的每個(gè)模塊,然后將這些模塊打包成一個(gè)或多個(gè) bundler,由瀏覽器加載

在了解 webpack 使用配置時(shí),我們必須首先要熟悉下面四個(gè)核心概念:

  • entry:入口
  • output:出口
  • loaders:加載器
  • plugins:插件

一、entry:入口

在 webpack 執(zhí)行處理應(yīng)用程序時(shí),會(huì)形成一個(gè)依賴關(guān)系圖表。在這個(gè)圖表的起點(diǎn)就是入口起點(diǎn)(entry point),進(jìn)入這個(gè)入口后,webpack 就可以計(jì)算出入口點(diǎn)依賴的模塊和庫。
如何在 webpack.config.js 中配置入口點(diǎn)呢?

單個(gè)入口語法

用法: entry: string |Array<sting>

// webpack.config.js
const config = {
  entry: './path/to/my/entry/file.js'
};

module.exports = config;

單個(gè)入口簡寫:

// webpack.config.js
const config = {
  entry: {
    main: './path/to/my/entry/file.js'
  }
};

當(dāng)你想要注入多個(gè)依賴文件時(shí),可以向 entry 屬性傳入一個(gè)數(shù)組,數(shù)組是由文件路徑組成。這樣可以快速地設(shè)置 webpack 的配置,創(chuàng)建“多個(gè)主入口(multi-main entry)”,但這種方法不利于配置的擴(kuò)展。

對象語法

用法:entry: {[entryChunkName: string]: string|Array<string>}

// webpack.config.js
const config = {
  entry: {
    app: './src/app.js',
    vendors: './src/vendors.js' 
  }
}

對象語法雖然繁瑣,但是它是應(yīng)用程序入口最可擴(kuò)展的方式。
**“可擴(kuò)展的 webpack 配置”是指,可重用并且可以與其他配置組合使用。用于將關(guān)注點(diǎn)從環(huán)境、構(gòu)建目標(biāo)、運(yùn)行時(shí)中分離。然后使用專門的工具(如 webpack-merge)將它們合并。

常用場景

1、分離應(yīng)用程序和第三方庫入口

// webpack.config.js
const config = {
  entry: {
    app: './src/app.js',
    vendors: './src/vendors.js'
  }
};

webpack 創(chuàng)建的依賴圖是彼此完全分離、相互獨(dú)立的,上述寫法比較適用于單頁面應(yīng)用程序。
執(zhí)行 webpack 時(shí),會(huì)使用 commonChunkPlugin 從 bundle 文件中提取 vendor 引用到 vendor bundle,并把引用 vendor 的部分替換為 webpack_require() 調(diào)用。
2、多頁面應(yīng)用程序

// webpack.config.js
const config = {
  entry: {
    pageOne: './src/pageOne/index.js',
    pageTwo: './src/pageTwo/index.js',
    pageThree: './src/pageThree/index.js'
  }
}

webpack 在多頁面應(yīng)用中,會(huì)使用 commonChunkPlugin 為每個(gè)頁面應(yīng)用創(chuàng)建 bundle 文件,在入口起點(diǎn)中時(shí)每個(gè)頁面都能對代碼和模塊實(shí)現(xiàn)復(fù)用。

二、output:輸出

這是屬性的作用是:控制 webpack 如何向硬盤寫入編譯文件。需要注意的是,即使是存在多個(gè)入口起點(diǎn),也只指定一個(gè)輸出配置
1、用法
在 output 屬性中需要配置 filename 和 path 兩個(gè)配置項(xiàng):

  • filename:輸出文件的文件名
  • path:目標(biāo)輸出的目錄,是一個(gè)絕對路徑
// webpack.config.js
const config = {
  output: {
    filename: 'bundle.js',
    path: '/home/proj/public/assets'
  }
};

module.exports = config;

此配置將一個(gè)單獨(dú)的 bundle.js 文件輸出到 /home/proj/public/assets 目錄中。
2、多個(gè)入口起點(diǎn)
如果配置中存在多個(gè)入口起點(diǎn),則需要使用一定的標(biāo)識符確保每個(gè)輸出的文件名的唯一性。

// webpack.config.js
{
  entry: {
    app: './src/app.js',
    search: './src/search.js'
  },
  output: {
    filename: '[name].js',
    path: __dirname + '/dist'
  }
}

// 寫入到硬盤:./dist/app.js, ./dist/search.js

為了確保每個(gè)輸出 bundle 名稱的唯一性,需要借用一下方式來替換:

// 1、使用入口名稱
filename: "[name].bundle.js"

// 2、使用內(nèi)部 chunk id
filename: "[id].bundle.js"

// 3、使用每次構(gòu)建生成的唯一的 hash 
filename: "[name].[hasn].bundle.js"

// 4、使用基于每個(gè) chunk 內(nèi)容的 hash
filename:“[chunkhash].bundle.js”

三、loader:加載器

loader 是用于對模塊的源代碼進(jìn)行轉(zhuǎn)換。在需要加載模塊時(shí)對其做預(yù)處理,它可以將文件從不同的語言(如 typescript)轉(zhuǎn)換為 JavaScript,或?qū)?nèi)聯(lián)圖像轉(zhuǎn)為 data URL,甚至允許你直接在 JavaScript 模塊中 import CSS文件。
1、使用 loader 的三種方式

  • 配置(推薦):在 webpack.config.js 文件中指定 loader
  • 內(nèi)聯(lián): 在每個(gè) import 語句中顯示指定 loader
  • CLI: 在 shell 命令中指定它們
    配置:
    在 modul.rules 中允許你在 webpack 配置中指定多個(gè)loader。
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [
          { loader: 'style-loader' },
          {
            loader: 'css-loader',
            options: {
              modules: true
            }
          }
        ]
      }
    ]
  }

內(nèi)聯(lián)

import Styles from 'style-loader!css-loader?modules!./styles.css';

使用 ! 將資源中的 loader 分開,分開的每部分都相對于當(dāng)前目錄解析。通過前置所有規(guī)則及使用 !,通過對選項(xiàng)傳遞查詢參數(shù),可以對應(yīng)覆蓋到配置中的任意 loader。
CLI

webpack --module-bind jade-loader --module-bind 'css=style-loader!css-loader'

上述是使用 webpack 命令,對 .jade 文件使用 jade-loader,對 .css 文件使用 style-loader 和 css-loader。
2、loader 所具有的特性

  • loader 支持鏈?zhǔn)絺鬟f。能夠?qū)Y源使用流水線(pipeline)。一組鏈?zhǔn)降?loader 將按照相反的順序執(zhí)行。loader 鏈中的第一個(gè)loader 返回值給下一個(gè) loader。在最后一二 loader,返回 webpack 所預(yù)期的 JavaScript。
  • loader 可以是同步的,也可以是異步的。
  • 運(yùn)行在node.js 中,并且能夠執(zhí)行任何可能的操作。
  • 接收查詢參數(shù),用于對 loader 傳遞配置
  • 可以使用 options 對象進(jìn)行配置
  • 除了使用package.json 常見的 main 屬性,還可以將普通的 你怕嗎 模塊導(dǎo)出為 loader
  • 插件可以為 loader 帶來更多特性
  • loader 能夠產(chǎn)生而外的任意文件

四、plugins:插件

webpack 中的插件的出現(xiàn),主要是為了實(shí)現(xiàn) loader 無法實(shí)現(xiàn)的功能,是webpack 中核心部分。
webpack 插件是一個(gè)具有 apply 屬性的 JavaScript 對象,apply 屬性會(huì)被 webpack 編譯器調(diào)用,并且編譯器對象可以在整個(gè)編譯生命周期訪問。
用法
在 webpack 配置中,你可以攜帶參數(shù)或者選項(xiàng),想 plugins 屬性中傳入 new 實(shí)例:
1、在配置中傳入 new 實(shí)例

// webpack.config.js
const HtmlWebpackPlugin = require('html-webpack-plugin'); //通過 npm 安裝
const webpack = require('webpack'); //訪問內(nèi)置的插件
const path = require('path');

const config = {
  entry: './path/to/my/entry/file.js',
  output: {
    filename: 'my-first-webpack.bundle.js',
    path: path.resolve(__dirname, 'dist')
  },
  module: {
    rules: [
      {
        test: /\.(js|jsx)$/,
        use: 'babel-loader'
      }
    ]
  },
  plugins: [
    new webpack.optimize.UglifyJsPlugin(),
    new HtmlWebpackPlugin({template: './src/index.html'})
  ]
};

module.exports = config;

2、Node API 傳入 new 實(shí)例


// 

戳我博客

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • GitChat技術(shù)雜談 前言 本文較長,為了節(jié)省你的閱讀時(shí)間,在文前列寫作思路如下: 什么是 webpack,它要...
    蕭玄辭閱讀 12,921評論 7 110
  • 版權(quán)聲明:本文為博主原創(chuàng)文章,未經(jīng)博主允許不得轉(zhuǎn)載。 webpack介紹和使用 一、webpack介紹 1、由來 ...
    it筱竹閱讀 11,492評論 0 21
  • 前言 webpack 是一個(gè)當(dāng)下最流行的前端資源的模塊打包器。當(dāng) webpack 處理應(yīng)用程序時(shí),它會(huì)遞歸地構(gòu)建一...
    weiqinl閱讀 10,423評論 6 9
  • 大家好,我是刀哥,繼續(xù)講服裝店銷售8步曲第3步。 銷售8部曲第3步 鼓勵(lì)試穿 為什么很多品牌已經(jīng)細(xì)化到將試穿作為K...
    小刀刀哥閱讀 1,758評論 0 1
  • 每一個(gè)人,每一條路,走的路或許有平行或許有相交,但每一個(gè)人在自己的世界里徜徉時(shí),不要總是以自己是走過那段路的經(jīng)驗(yàn)高...
    跳跳呆閱讀 1,494評論 0 2

友情鏈接更多精彩內(nèi)容