閱讀《深入淺出Webpack》和官方文檔 -- 基礎(chǔ)

基礎(chǔ)

  1. 模塊化

CommonJS: 用于Node.js環(huán)境

// 導(dǎo)出
module.exports = moduleA.func;
// 導(dǎo)入
const moduleA = require( url );

AMD: 用于Node.js環(huán)境,瀏覽器雹食。異步方式家在模塊 -> requirejs

// 定義模塊
define( 'module', ['dep'], function(dep) {
  return exports;
} )
// 導(dǎo)入模塊
require( ['module'], function(module) {} )

ES6模塊化: 需要轉(zhuǎn)化成es5運(yùn)行

// 導(dǎo)出
export function  hello(){};
export default {};
// 導(dǎo)入
import { A } from url;
import B from url;

一直計(jì)劃說(shuō)詳細(xì)學(xué)一下webpack皂岔,然后由于各種因素拖到了現(xiàn)在条辟。 結(jié)合《深入淺出Webpack》和官方文檔俱萍。

概念: 靜態(tài)模塊打包器(module bundler)整袁, 將從入口開(kāi)始 構(gòu)建整個(gè)應(yīng)用的依賴(lài)關(guān)系圖挽拂,然后將所有模塊打包成一個(gè)或者多個(gè)bundle。

  • 入口(entry): 應(yīng)用從哪個(gè)文件作為依賴(lài)圖的開(kāi)始人灼。
  • 出口(output): 在哪里輸出根據(jù)依賴(lài)圖所創(chuàng)建的bundles围段, 以及如何命名這些文件⊥斗牛【默認(rèn)為./dist】
  • 插件(plugins): loader 被用于轉(zhuǎn)換某些類(lèi)型的模塊奈泪,而插件則可以用于執(zhí)行范圍更廣的任務(wù)。插件的范圍包括灸芳,從打包優(yōu)化和壓縮段磨,一直到重新定義環(huán)境中的變量。
  • 模式(mode): 可以啟用響應(yīng)模式下的webpack內(nèi)置的優(yōu)化(development耗绿, production)
  • Chunk: 一個(gè)chunk由多個(gè)模塊組成苹支, 用于代碼合并與分割。
  • module: 處理模塊的規(guī)則
  • resolve:尋找模塊的規(guī)則

1. Entry: 可配置 多頁(yè)面應(yīng)用 或者 多入口的單頁(yè)應(yīng)用

const config = {
  entry: './path/to/my/entry/file.js'   // string 類(lèi)型
};
const config = {
  entry: ['./path/to/my/entry/file1.js', './path/to/my/entry/file2.js']   // array 類(lèi)型  
  // 數(shù)組里的最后一個(gè)入口文件的模塊會(huì)被導(dǎo)出误阻。
};
const config = {
  entry: {  // object 類(lèi)型
      pc:  './pc/pc.js',
      h5:  './h5/h5.js',
  } 
};

2. Output:

 const config = {
  output: {
    filename: "",  // string 類(lèi)型
    chunkFilename: ""债蜜, // string  需要在runtime根據(jù)chunk發(fā)送的請(qǐng)求去生成
    path: path.resolve(__dirname, 'dist/assets'),
    publicPath: ""究反, // 靜態(tài)資源的路徑寻定。 需要按照開(kāi)發(fā)環(huán)境或者生產(chǎn)環(huán)境配置
    library:"", // string 導(dǎo)出庫(kù)的名稱(chēng)
    libraryTarget: "",  // enum  已何種方式導(dǎo)出庫(kù)
    libraryExport: "", // string, array 導(dǎo)出那些子模塊
  }
};

內(nèi)置變量列表:

  1. id: Chunk的唯一標(biāo)識(shí)精耐, 從0開(kāi)始
  2. name: Chunk的名稱(chēng)
  3. hash:Chunk的唯一標(biāo)識(shí)的Hash值
  4. chunkhash: Chunk內(nèi)容的Hash值
  5. query 模塊文件名 狼速? 后面的字符串
    注: Hash的長(zhǎng)度是可以指定的如:[hash:8] ,默認(rèn)20
    其他配置項(xiàng) 在官方文檔中有介紹或者后續(xù)的筆記中更新卦停。

3. Module: 如何處理不同類(lèi)型的模塊

 const config = {
  module: {
    noParse: /jquery/ ,  // 忽略部分文件的解析和處理( 被忽略的文件不該包含import, require, define)
    rules: [  // 配置Loader
      {
        test: /\.css/,   //  正則表達(dá)式的匹配規(guī)則向胡, 也可是個(gè)array
        use: [],  // 數(shù)組中可以是string, object
        enforce: "pre", // enum  ["pre", "post"] 
        include: path.resolve(__dirname, 'src')惊完,// 僅匹配src目錄中的文件
        exclude: path.resolve(__dirname, 'dist')僵芹,// 排除dist目錄中的文件
        and: [],  // 必須匹配所有條件
        or: [],
        not: [],
      }
    ],
    parser: {  // 指定解析器的開(kāi)關(guān), 精確控制哪些語(yǔ)法可以被解析
       amd: false,
       commonjs: true,
    }   
  }
};

其中當(dāng)use中,設(shè)置為對(duì)象時(shí)小槐, 可以向其loader傳入多個(gè)參數(shù)

  use: [
    {
      loader: "",  //  所使用的loader
      options: {},  // 向loader傳入的參數(shù)
    }
  ]

使用oneOf拇派,對(duì)匹配規(guī)則進(jìn)行嵌套,

    rules: [  // 配置Loader
      {
        test:  /\.css/,
        oneOf: [ // 可以指定嵌套規(guī)則
          {
            resourceQuery: /inline/, // foo.css?inline
            use: 'url-loader'
          },
          {
            resourceQuery: /external/, // foo.css?external
            use: 'file-loader'
          }
        ], 
      }
    ]

配置loader 通過(guò)一下方式完成:

  1. 條件匹配: 通過(guò)test,include件豌,exclude
  2. 應(yīng)用規(guī)則: 通過(guò)use應(yīng)用loader
  3. 重置順序: 默認(rèn)loader的順序是從右向左的疮方, 使用enforce選項(xiàng)將loader的執(zhí)行順序改變

webpack自帶的loader庫(kù)

4. Resolve: 模塊如何被解析, (webpack本身含有默認(rèn)值)

const config = {
  resolve: {
    alias: { // 創(chuàng)建別名茧彤。 使引用是更方便骡显,避免過(guò)多的相對(duì)路徑
      images: path.resolve(__dirname, 'src/images/')
      css$: path.resolve(__dirname, 'src/assets/css')  // $ 標(biāo)識(shí)精準(zhǔn)匹配
    },
    extensions: [".js",".json"], // 當(dāng)無(wú)后綴名時(shí),默認(rèn)自動(dòng)帶上后綴解析
    mainFiles: [], // 指定導(dǎo)入模塊時(shí) 導(dǎo)入的哪部分代碼
    modules: ["node_modules"], // 默認(rèn)只去node_modules中尋找第三方模塊
    enforceExtension: false, // 允許無(wú)擴(kuò)展名文件的引用
    unsafeCache: /\aa/, // 開(kāi)啟僅緩存aa模塊  regex, array, boolean
    plugins: [],  // 額外的解析插件列表
  }
}

mainFiles棘街, 默認(rèn)為["browser", "module", "main"], 默認(rèn)順序
在其他target時(shí)蟆盐, 默認(rèn)為["module","main"]
即 對(duì)應(yīng) 所引用包的package.json中的

{
  main: "build/d3.Node.js",
  browser: "build/d3.js",
  module: "index",
}

5. Plugins

const config = {
 plugins: [ // array
     // 每項(xiàng)是一個(gè)插件的實(shí)例承边, 將參數(shù)通過(guò)構(gòu)造函數(shù)傳入
     new CommonsChunkPlugin({  // 將所有公共代碼提取到common代碼塊中
       name: "common",
       chunks: ["a","b"]
     })
 ]
}

Webpack自帶的插件庫(kù)

6. DevServer: 在開(kāi)發(fā)中的行為

const config = {
 devServer: {
   host: "", // 默認(rèn)為localhost遭殉, 設(shè)置為ip 供外部訪(fǎng)問(wèn)
   port: "", // 監(jiān)聽(tīng)的端口, 默認(rèn)8080
   inline: true,  // false 時(shí) 責(zé)啟用iframe模式博助, true為嵌入bundle中
   allowedHosts: [], // 設(shè)置白名單
   compress: true, //  啟用gzip壓縮
   contentBase: path.join(__dirname, "public"), // 從哪提取靜態(tài)文件, 默認(rèn)當(dāng)前執(zhí)行的目錄 ./
   disableHostCheck: false,  // 關(guān)閉host檢查险污,使其他設(shè)備也能訪(fǎng)問(wèn)本地服務(wù)
   lazy: true, // 開(kāi)啟惰性模式,僅在請(qǐng)求時(shí)編譯富岳,即不監(jiān)聽(tīng)文件改動(dòng)
   filename: "", // 只在請(qǐng)求該文件時(shí)編譯蛔糯, 必須開(kāi)啟惰性模式
   headers: {},  // 在所有想用中添加首部?jī)?nèi)容
   hot: true, // 開(kāi)啟模塊熱替換,僅刷新改變的模塊
   clientLogLevel: "info",  // enum 客戶(hù)端的日志級(jí)別窖式,默認(rèn)info
   https: true, // 默認(rèn)使用http服務(wù)蚁飒,開(kāi)啟https 后自動(dòng)生成一份證書(shū),也可用{}配置自己的證書(shū),讀文件
   open: true,  // 第一次構(gòu)建后 自動(dòng)打開(kāi)瀏覽器
   proxy: {
     "/api":  "http://localhost:3000",
     "/users": {
       target: "https://localhost:3000",
       pathRewrite: {"^/users" : ""},  // 將路徑重寫(xiě) 如 /users/login -> /login
       secure: false, // 若代理到https服務(wù)萝喘,則需要將secure設(shè)為false
       bypass: function(req, res, proxyOptions) {
         if (req.headers.accept.indexOf("html") !== -1) {
           console.log("Skipping proxy for browser request.");
           return "/index.html";
         }
       }
     }
   },
   quiet:  true, // 除初始啟動(dòng)信息外都不會(huì)打印到控制臺(tái)
 }
}
  proxy: [{  // 針對(duì)多個(gè)請(qǐng)求 進(jìn)行代理
    context: ["/auth", "/api"],
    target: "http://localhost:3000",
  }]

7. Devtool:配置source map

const config = {
  devtool: "none" // 構(gòu)建source-map方便調(diào)試  enum 
}

具體的選項(xiàng)和構(gòu)建速度 在官方文檔中有詳細(xì)的表格

8. Target:配置source map

const config = {
  target: "web",  // enum 默認(rèn)web淮逻, 還有node,webworker阁簸, electron等  
const webpack = require("webpack");

const options = {
  target: (compiler) => {  // function  使用非自帶的target的插件
    compiler.apply(
      new webpack.JsonpTemplatePlugin(options.output),
      new webpack.LoaderTargetPlugin("web")
    );
  }
};

9. Watch: 監(jiān)聽(tīng)規(guī)則

const config = {
  watch: true, //  默認(rèn)false爬早, 在devServer中默認(rèn)開(kāi)啟
  watchOptions: {
    ignored: /node_modules/,  // 或者使用"files/**/*.js" 這種形式
    poll: 1000, // number, boolean 每秒進(jìn)行輪詢(xún)
    aggregateTimeout: 300, // 監(jiān)聽(tīng)到變化后 延遲300ms再執(zhí)行
  }
}

10. Externals不打包某些模塊

const config = {
  externals: {
    jquery: 'jQuery'  //  string, array. object, function, regex
  }
}

因?yàn)槿忠肓艘恍┠K或變量,然后import的時(shí)候启妹,會(huì)使webpack將模塊再打包一次筛严,所以會(huì)出現(xiàn)重復(fù)的內(nèi)容,使用externals排除在外饶米。

11. Performance

const config = {
  performance: {
    hints: "warning"桨啃,  //  打開(kāi)提示,在開(kāi)發(fā)環(huán)境使用warning檬输,生產(chǎn)error
    maxEntrypointSize: 400000, //  根據(jù)入口起點(diǎn)的最大體積优幸,控制 webpack 何時(shí)生成性能提示  默認(rèn)值 250000 bytes
    maxAssetSize: 100000, // 根據(jù)單個(gè)資源體積,控制 webpack 何時(shí)生成性能提示
    assetFilter: function(assetFilename) {  // 只給出 .js 文件的性能提示褪猛。
      return assetFilename.endsWith('.js');
    }
  }
}

12. Stats

stats: "minimal", // string  enum  只在發(fā)生錯(cuò)誤或有新的編譯時(shí)輸出
stats: {}, // 使用對(duì)象對(duì)統(tǒng)計(jì)信息 進(jìn)行更精確的控制

至此 网杆,文檔中的概念,配置,Loaders碳却, plugins 已完成概覽队秩。接下來(lái)抽空完成,實(shí)戰(zhàn)昼浦, 優(yōu)化馍资, 原理。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末关噪,一起剝皮案震驚了整個(gè)濱河市鸟蟹,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌使兔,老刑警劉巖建钥,帶你破解...
    沈念sama閱讀 219,270評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異虐沥,居然都是意外死亡熊经,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,489評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)欲险,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)镐依,“玉大人,你說(shuō)我怎么就攤上這事天试』笨牵” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,630評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵喜每,是天一觀(guān)的道長(zhǎng)务唐。 經(jīng)常有香客問(wèn)我,道長(zhǎng)灼卢,這世上最難降的妖魔是什么绍哎? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,906評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮鞋真,結(jié)果婚禮上崇堰,老公的妹妹穿的比我還像新娘。我一直安慰自己涩咖,他們只是感情好海诲,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,928評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布群扶。 她就那樣靜靜地躺著蕊蝗,像睡著了一般。 火紅的嫁衣襯著肌膚如雪辰企。 梳的紋絲不亂的頭發(fā)上闸昨,一...
    開(kāi)封第一講書(shū)人閱讀 51,718評(píng)論 1 305
  • 那天蚯斯,我揣著相機(jī)與錄音薄风,去河邊找鬼。 笑死拍嵌,一個(gè)胖子當(dāng)著我的面吹牛遭赂,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播横辆,決...
    沈念sama閱讀 40,442評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼撇他,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了狈蚤?” 一聲冷哼從身側(cè)響起困肩,我...
    開(kāi)封第一講書(shū)人閱讀 39,345評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎脆侮,沒(méi)想到半個(gè)月后锌畸,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,802評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡他嚷,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,984評(píng)論 3 337
  • 正文 我和宋清朗相戀三年蹋绽,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了芭毙。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片筋蓖。...
    茶點(diǎn)故事閱讀 40,117評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖退敦,靈堂內(nèi)的尸體忽然破棺而出粘咖,到底是詐尸還是另有隱情,我是刑警寧澤侈百,帶...
    沈念sama閱讀 35,810評(píng)論 5 346
  • 正文 年R本政府宣布瓮下,位于F島的核電站,受9級(jí)特大地震影響钝域,放射性物質(zhì)發(fā)生泄漏讽坏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,462評(píng)論 3 331
  • 文/蒙蒙 一例证、第九天 我趴在偏房一處隱蔽的房頂上張望路呜。 院中可真熱鬧,春花似錦织咧、人聲如沸胀葱。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,011評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)抵屿。三九已至,卻和暖如春捅位,著一層夾襖步出監(jiān)牢的瞬間轧葛,已是汗流浹背搂抒。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,139評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留尿扯,地道東北人燕耿。 一個(gè)月前我還...
    沈念sama閱讀 48,377評(píng)論 3 373
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像姜胖,于是被迫代替她去往敵國(guó)和親誉帅。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,060評(píng)論 2 355

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

  • GitChat技術(shù)雜談 前言 本文較長(zhǎng)右莱,為了節(jié)省你的閱讀時(shí)間蚜锨,在文前列寫(xiě)作思路如下: 什么是 webpack,它要...
    蕭玄辭閱讀 12,697評(píng)論 7 110
  • 版權(quán)聲明:本文為博主原創(chuàng)文章氛悬,未經(jīng)博主允許不得轉(zhuǎn)載。 webpack介紹和使用 一耘柱、webpack介紹 1如捅、由來(lái) ...
    it筱竹閱讀 11,140評(píng)論 0 21
  • 說(shuō)在前面:這些文章均是本人花費(fèi)大量精力研究整理,如有轉(zhuǎn)載請(qǐng)聯(lián)系作者并注明引用调煎,謝謝本文的受眾人群不是webpack...
    RockSAMA閱讀 6,927評(píng)論 2 7
  • 我問(wèn)他镜遣,你喜歡我什么啊。 他想了想士袄,說(shuō)不知道悲关,太多了。 那好吧娄柳,你乖乖的繼續(xù)喜歡我好了寓辱。 關(guān)于你必須愛(ài)我的理由,我...
    八命先生閱讀 4,011評(píng)論 21 110
  • 乘坐412路公交車(chē)從女王街出發(fā)赤拒,刷go card卡秫筏。20分鐘就到達(dá)了著名的昆士蘭大學(xué)校門(mén)口。即使頭頂陽(yáng)光正...
    wind2019閱讀 335評(píng)論 0 2