webpack常用loader和plugin

webpack是一個(gè)模塊打包器(module bundler),提供了一個(gè)核心犬钢,核心提供了很多開(kāi)箱即用的功能,同時(shí)它可以用loader和plugin來(lái)擴(kuò)展。webpack本身結(jié)構(gòu)精巧耘戚,基于tapable的插件架構(gòu),擴(kuò)展性強(qiáng)操漠,眾多的loader或者plugin讓webpack顯得很復(fù)雜收津。
webpack常用配置包括:devtool、entry浊伙、 output撞秋、module、resolve嚣鄙、plugins吻贿、externals等,本文主要介紹下webpack常用的loader和plugin

webpack允許我們使用loader來(lái)處理文件哑子,loader是一個(gè)導(dǎo)出為function的node模塊舅列。可以將匹配到的文件進(jìn)行一次轉(zhuǎn)換卧蜓,同時(shí)loader可以鏈?zhǔn)絺鬟f剧蹂。

loader的使用方式

一般loader的使用方式分為三種:
1:在配置文件webpack.config.js中配置

module.exports = {
  module: {
    rules: [
      {
        test: /\.txt$/,
        use: 'raw-loader'
      }
    ]
  }
}復(fù)制代碼

2:通過(guò)命令行參數(shù)方式

webpack --module-bind 'txt=raw-loader'復(fù)制代碼

3:通過(guò)內(nèi)聯(lián)使用

import txt from 'raw-loader!./file.txt';復(fù)制代碼

webpack常用的loader

  • 樣式:style-loader、css-loader烦却、less-loader宠叼、sass-loader等
  • 文件:raw-loader、file-loader 其爵、url-loader等
  • 編譯:babel-loader冒冬、coffee-loader 、ts-loader等
  • 校驗(yàn)測(cè)試:mocha-loader摩渺、jshint-loader 简烤、eslint-loader等

比如下面配置,可以匹配.scss的文件摇幻,分別經(jīng)過(guò)sass-loader横侦、css-loader、style-loader的處理绰姻。
sass-loader轉(zhuǎn)化sass為css文件枉侧,并且包一層module.exports成為一個(gè)js module。style-loader將創(chuàng)建一個(gè)style標(biāo)簽將css文件嵌入到html中狂芋。css-loader則處理其中的@import和url()榨馁。

module.exports = {
  module: {
    rules: [
        {
          test: /\.scss$/,
          use:[
              {loader:'style-loader'},
              {loader:'css-loader',options:{sourceMap:true,modules:true}},
              {loader:'sass-loader',options:{sourceMap:true}}
          ],
          exclude:/node_modules/
      }
    ]
  }
}復(fù)制代碼
  • vue-loader、coffee-loader帜矾、babel-loader等可以將特定文件格式轉(zhuǎn)成js模塊翼虫、將其他語(yǔ)言轉(zhuǎn)化為js語(yǔ)言和編譯下一代js語(yǔ)言

  • file-loader屑柔、url-loader等可以處理資源,file-loader可以復(fù)制和放置資源位置珍剑,并可以指定文件名模板掸宛,用hash命名更好利用緩存。

  • url-loader可以將小于配置limit大小的文件轉(zhuǎn)換成內(nèi)斂Data Url的方式招拙,減少請(qǐng)求旁涤。

  • raw-loader可以將文件已字符串的形式返回

  • imports-loader、exports-loader等可以向模塊注入變量或者提供導(dǎo)出模塊功能迫像,常見(jiàn)場(chǎng)景是:
    1:jquery插件注入,imports-loader?=jquery
    2:禁用AMD劈愚,imports-loader?define=false
    等同于:var $ = require("jquery") 和 var define = false;

  • expose-loader:暴露對(duì)象為全局變量
    如何寫一個(gè)loader:官網(wǎng)介紹how to write a loader
    下面是一個(gè)簡(jiǎn)單的raw-loader,它可以將文本類文件轉(zhuǎn)成字符串到j(luò)s文件中。其中this.cacheable闻妓、this.value等是loader的api菌羽,分別是將結(jié)果標(biāo)記為可緩存和把值傳遞給下一個(gè)loader。

    module.exports = function(content) {
      this.cacheable && this.cacheable();
      this.value = content;
      return "module.exports = " + JSON.stringify(content);
    }復(fù)制代碼
    

    webpack的plugin比loader強(qiáng)大由缆,通過(guò)鉤子可以涉及整個(gè)構(gòu)建流程注祖,可以做一些在構(gòu)建范圍內(nèi)的事情。

webpack常用的plugin

  • 官網(wǎng)介紹plugins

  • 第三方插件awesome-webpack

  • 首先webpack內(nèi)置UglifyJsPlugin均唉,壓縮和混淆代碼是晨。

  • webpack內(nèi)置CommonsChunkPlugin,提高打包效率舔箭,將第三方庫(kù)和業(yè)務(wù)代碼分開(kāi)打包罩缴。

  • ProvidePlugin:自動(dòng)加載模塊,代替require和import

      new webpack.ProvidePlugin({
        $: 'jquery',
        jQuery: 'jquery'
      })復(fù)制代碼
    
  • html-webpack-plugin可以根據(jù)模板自動(dòng)生成html代碼层扶,并自動(dòng)引用css和js文件

  • extract-text-webpack-plugin 將js文件中引用的樣式單獨(dú)抽離成css文件

  • DefinePlugin 編譯時(shí)配置全局變量箫章,這對(duì)開(kāi)發(fā)模式和發(fā)布模式的構(gòu)建允許不同的行為非常有用。

    new webpack.DefinePlugin({
      PRODUCTION: JSON.stringify(true),
      VERSION: JSON.stringify("5fa3b9"),
      BROWSER_SUPPORTS_HTML5: true,
      TWO: "1+1",
      "typeof window": JSON.stringify("object")
    })復(fù)制代碼
    
  • HotModuleReplacementPlugin 熱更新

    • 添加HotModuleReplacementPlugin
    • entry中添加 "webpack-dev-server/client?http://localhost:8080/",
    • entry中添加 "webpack/hot/dev-server"
    • (熱更新還可以直接用webpack_dev_server --hot --inline,原理也是在entry中添加了上述代碼)
  • webpack 內(nèi)置的DllPluginDllReferencePlugin相互配合镜会,前置第三方包的構(gòu)建檬寂,只構(gòu)建業(yè)務(wù)代碼,同時(shí)能解決Externals多次引用問(wèn)題戳表。DllReferencePlugin引用DllPlugin配置生成的manifest.json文件,manifest.json包含了依賴模塊和module id的映射關(guān)系

  • babili-webpack-plugin桶至、transform-runtime 、transform-object-rest-spread

    • babili-webpack-plugin:構(gòu)建在babel之上 why
    • transform-runtime :解決了babel在每個(gè)文件都插入了輔助代碼匾旭,代碼體積過(guò)大的問(wèn)題镣屹。
    • transform-object-rest-spread:
      Transform rest properties for object destructuring assignment and spread properties for object literals
      為對(duì)象字面量添加解構(gòu)賦值和spread屬性
  • optimize-css-assets-webpack-plugin 不同組件中重復(fù)的css可以快速去重

  • webpack-bundle-analyzer 一個(gè)webpack的bundle文件分析工具,將bundle文件以可交互縮放的treemap的形式展示季率。

  • compression-webpack-plugin 生產(chǎn)環(huán)境可采用gzip壓縮JS和CSS

  • happypack:通過(guò)多進(jìn)程模型野瘦,來(lái)加速代碼構(gòu)建

        const os = require('os');
        let HappyPack = require('happypack');
        let happyThreadPool = HappyPack.ThreadPool({size: os.cpus().length});
        exports.plugins = [
          new HappyPack({
            id: 'jsx',
            threadPool: happyThreadPool,
            loaders: [ 'babel-loader' ]
          }),
    
          new HappyPack({
            id: 'coffeescripts',
            threadPool: happyThreadPool,
            loaders: [ 'coffee-loader' ]
          })
        ];
    
        exports.module.loaders = [
          {
            test: /\.js$/,
            loaders: [ 'happypack/loader?id=jsx' ]
          },
          {
            test: /\.coffee$/,
            loaders: [ 'happypack/loader?id=coffeescripts' ]
          },
        ]復(fù)制代碼
    

寫一個(gè)webpack插件:

官網(wǎng)介紹:how to write a plugin

主要的步驟如下:
  • 編寫一個(gè)JavaScript命名函數(shù)描沟。
  • 在它的原型上定義一個(gè)apply方法飒泻。
  • 指定掛載的webpack事件鉤子鞭光。
  • 處理webpack內(nèi)部實(shí)例的特定數(shù)據(jù)。
  • 功能完成后調(diào)用webpack提供的回調(diào)泞遗。
    編寫插件之前要理解compiler和compilation兩個(gè)對(duì)象惰许,以及webpack生命周期的各個(gè)階段和鉤子,plugin比loader強(qiáng)大史辙,通過(guò)plugin你可以訪問(wèn)compliler和compilation過(guò)程汹买,通過(guò)鉤子攔截webpack的執(zhí)行。

比如我們可以在構(gòu)建生成文件時(shí)聊倔,將所有生成的文件名生成到filelist.md的文件中

webpack會(huì)將compilation.assets的內(nèi)容生成文件晦毙,所以可以在構(gòu)建中利用它生成我們想要的文件。

function FileListPlugin(options) {}
FileListPlugin.prototype.apply = function(compiler) {
  compiler.plugin('emit', function(compilation, callback) {
    var filelist = 'In this build:\n\n';
    for (var filename in compilation.assets) {
      filelist += ('- '+ filename +'\n');
    }
    compilation.assets['filelist.md'] = {
      source: function() {
        return filelist;
      },
      size: function() {
        return filelist.length;
      }
    };
    callback();
  });
};

module.exports = FileListPlugin;復(fù)制代碼

比如我們可以在html-webpack-plugin生成文件后刷新頁(yè)面耙蔑,完成熱更新效果见妒。

var webpack = require('webpack')
var webpackConfig = require('./webpack.config')
var compiler = webpack(webpackConfig)
var hotMiddleware = require('webpack-hot-middleware')(compiler, {
  log: () => {}
})
compiler.plugin('compilation', function (compilation) {
  compilation.plugin('html-webpack-plugin-after-emit', function (data, cb) {
    hotMiddleware.publish({ action: 'reload' })
    cb()
  })
})復(fù)制代碼

比如我們可以在構(gòu)建完成后,打開(kāi)一個(gè)提示窗口甸陌。

class Notifier {
  apply(compiler) {
    compiler.plugin("done", (stats) => {
      const pkg = require("./package.json");
      const notifier = require("node-notifier");
      const time = ((stats.endTime - stats.startTime) / 1000).toFixed(2);

      notifier.notify({
        title: pkg.name,
        message: `WebPack is done!\n${stats.compilation.errors.length} errors in ${time}s`,
        contentImage: "https://path/to/your/logo.png",
      });
    });
  }
}

module.exports = Notifier;
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末须揣,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子钱豁,更是在濱河造成了極大的恐慌耻卡,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,496評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件牲尺,死亡現(xiàn)場(chǎng)離奇詭異卵酪,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)谤碳,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,407評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門凛澎,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人估蹄,你說(shuō)我怎么就攤上這事塑煎。” “怎么了臭蚁?”我有些...
    開(kāi)封第一講書(shū)人閱讀 162,632評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵最铁,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我垮兑,道長(zhǎng)冷尉,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,180評(píng)論 1 292
  • 正文 為了忘掉前任系枪,我火速辦了婚禮雀哨,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己雾棺,他們只是感情好膊夹,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,198評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著捌浩,像睡著了一般放刨。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上尸饺,一...
    開(kāi)封第一講書(shū)人閱讀 51,165評(píng)論 1 299
  • 那天进统,我揣著相機(jī)與錄音,去河邊找鬼浪听。 笑死螟碎,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的迹栓。 我是一名探鬼主播抚芦,決...
    沈念sama閱讀 40,052評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼迈螟!你這毒婦竟也來(lái)了叉抡?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 38,910評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤答毫,失蹤者是張志新(化名)和其女友劉穎褥民,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體洗搂,經(jīng)...
    沈念sama閱讀 45,324評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡消返,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,542評(píng)論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了耘拇。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片撵颊。...
    茶點(diǎn)故事閱讀 39,711評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖惫叛,靈堂內(nèi)的尸體忽然破棺而出倡勇,到底是詐尸還是另有隱情,我是刑警寧澤嘉涌,帶...
    沈念sama閱讀 35,424評(píng)論 5 343
  • 正文 年R本政府宣布妻熊,位于F島的核電站,受9級(jí)特大地震影響仑最,放射性物質(zhì)發(fā)生泄漏扔役。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,017評(píng)論 3 326
  • 文/蒙蒙 一警医、第九天 我趴在偏房一處隱蔽的房頂上張望亿胸。 院中可真熱鬧坯钦,春花似錦、人聲如沸侈玄。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,668評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)拗馒。三九已至路星,卻和暖如春溯街,著一層夾襖步出監(jiān)牢的瞬間诱桂,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,823評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工呈昔, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留挥等,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,722評(píng)論 2 368
  • 正文 我出身青樓堤尾,卻偏偏與公主長(zhǎng)得像肝劲,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子郭宝,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,611評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容

  • 編寫 Loader Loader就像是一個(gè)翻譯員辞槐,能把源文件經(jīng)過(guò)轉(zhuǎn)化后輸出新的結(jié)果,并且一個(gè)文件還可以鏈?zhǔn)降慕?jīng)過(guò)多...
    oWSQo閱讀 7,588評(píng)論 0 8
  • 在現(xiàn)在的前端開(kāi)發(fā)中粘室,前后端分離榄檬、模塊化開(kāi)發(fā)、版本控制衔统、文件合并與壓縮鹿榜、mock數(shù)據(jù)等等一些原本后端的思想開(kāi)始...
    Charlot閱讀 5,439評(píng)論 1 32
  • 目錄第1章 webpack簡(jiǎn)介 11.1 webpack是什么? 11.2 官網(wǎng)地址 21.3 為什么使用 web...
    lemonzoey閱讀 1,734評(píng)論 0 1
  • 模塊化 CommonJS CommonJS是一種使用廣泛的 JavaScript模塊化規(guī)范锦爵,核心思想是通過(guò) req...
    小小的白菜閱讀 585評(píng)論 0 12
  • 我小時(shí)候并不是一個(gè)膽大頑皮的孩子舱殿,比較喜歡宅在家里,活在自己的思想中险掀。也許男孩子記事兒比較晚沪袭,我比較深刻的回憶是大...
    冠淳老師閱讀 776評(píng)論 5 11