webpack多頁應用架構系列(二):webpack配置經常使用部分有哪些?

本文首發於 Array_Huang的技術博客—— 實用至上,非經做者贊成,請勿轉載。
原文地址: http://www.javashuo.com/article/p-eihwhadk-kg.html
若是您對本系列文章感興趣,歡迎關注訂閱這裏: https://segmentfault.com/blog/array_huang

前言

webpack的配置文件是一個node.js的module,用CommonJS風格來書寫,形如:javascript

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

webpack的配置文件並無固定的命名,也沒有固定的路徑要求,若是你直接用webpack來執行編譯,那麼webpack默認讀取的將是當前目錄下的webpack.config.jscss

$ pwd
/d/xampp/htdocs/webpack-seed
$ webpack # webpack此時讀取的其實是/d/xampp/htdocs/webpack-seed/webpack.config.js

若是你有其它命名的須要或是你有多份配置文件,可使用--config參數傳入路徑:html

$ webpack --config ./webpackConfig/dev.config.js

另外,在CLI執行webpack指令時可傳入的參數(固然除了--config)實際上均可以在配置文件裏面直接聲明,我強烈建議能夠的話儘可能都在配置文件裏寫好,有須要的話寫兩份配置也好三份也好(反正配置文件間也是能夠互相引用的,相同的部分就拆成一個module出來以供讀取,最後拼成各類狀況下須要的配置就行了)。前端

入口文件配置:entry參數

entry能夠是字符串(單入口),能夠是數組(多入口),但爲了後續發展,請務必使用object,由於object中的key在webpack裏至關於此入口的name,既能夠後續用來拼生成文件的路徑,也能夠用來做爲此入口的惟一標識。
我推薦的形式是這樣的:java

entry: { // pagesDir是前面準備好的入口文件集合目錄的路徑
  'alert/index': path.resolve(pagesDir, `./alert/index/page`), 
  'index/login': path.resolve(pagesDir, `./index/login/page`), 
  'index/index': path.resolve(pagesDir, `./index/index/page`),
},

對照個人腳手架項目webpack-seed的文件目錄結構,就很清楚了:node

├─src # 當前項目的源碼
    ├─pages # 各個頁面獨有的部分,如入口文件、只有該頁面使用到的css、模板文件等
    │  ├─alert # 業務模塊
    │  │  └─index # 具體頁面
    │  ├─index # 業務模塊
    │  │  ├─index # 具體頁面
    │  │  └─login # 具體頁面

因爲每個入口文件都至關於entry裏的一項,所以這樣一項一項地來寫實在是有點繁瑣,我就稍微寫了點代碼來拼接這entry:webpack

var pageArr = [
    'index/login',
    'index/index',
    'alert/index',
  ];
  var configEntry = {};
  pageArr.forEach((page) => {
    configEntry[page] = path.resolve(pagesDir, page + '/page');
  });

輸出文件:output參數

output參數告訴webpack以什麼方式來生成/輸出文件,值得注意的是,與entry不一樣,output至關於一套規則,全部的入口都必須使用這一套規則,不能針對某一個特定的入口來制定output規則。output參數裏有這幾個子參數是比較經常使用的:path、publicPath、filename、chunkFilename,這裏先給個webpack-seed中的示例:git

output: {
      path: buildDir, // var buildDir = path.resolve(__dirname, './build');
      publicPath: '../../../../build/',
      filename: '[name]/entry.js',    // [name]表示entry每一項中的key,用以批量指定生成後文件的名稱
      chunkFilename: '[id].bundle.js',
    },

path

path參數表示生成文件的根目錄,須要傳入一個絕對路徑。path參數和後面的filename參數共同組成入口文件的完整路徑。github

publicPath

publicPath參數表示的是一個URL路徑(指向生成文件的根目錄),用於生成css/js/圖片/字體文件等資源的路徑,以確保網頁能正確地加載到這些資源。
publicPath參數跟path參數的區別是:path參數實際上是針對本地文件系統的,而publicPath則針對的是瀏覽器;所以,publicPath既能夠是一個相對路徑,如示例中的'../../../../build/',也能夠是一個絕對路徑如http://www.xxxxx.com/。通常來講,我仍是更推薦相對路徑的寫法,這樣的話總體遷移起來很是方便。那何時用絕對路徑呢?其實也很簡單,當你的html文件跟其它資源放在不一樣的域名下的時候,就應該用絕對路徑了,這種狀況很是多見於後端渲染模板的場景。web

filename

filename屬性表示的是如何命名生成出來的入口文件,規則有如下三種:

  • [name],指代入口文件的name,也就是上面提到的entry參數的key,所以,咱們能夠在name裏利用/,便可達到控制文件目錄結構的效果。
  • [hash],指代本次編譯的一個hash版本,值得注意的是,只要是在同一次編譯過程當中生成的文件,這個[hash]的值就是同樣的;在緩存的層面來講,至關於一次全量的替換。
  • [chunkhash],指代的是當前chunk的一個hash版本,也就是說,在同一次編譯中,每個chunk的hash都是不同的;而在兩次編譯中,若是某個chunk根本沒有發生變化,那麼該chunk的hash也就不會發生變化。這在緩存的層面上來講,就是把緩存的粒度精細到具體某個chunk,只要chunk不變,該chunk的瀏覽器緩存就能夠繼續使用。

下面來講說如何利用filename參數和path參數來設計入口文件的目錄結構,如示例中的path: buildDir, // var buildDir = path.resolve(__dirname, './build');filename: '[name]/entry.js',那麼對於key爲'index/login'的入口文件,生成出來的路徑就是build/index/login/entry.js了,怎麼樣,是否是很簡單呢?

chunkFilename

chunkFilename參數與filename參數相似,都是用來定義生成文件的命名方式的,只不過,chunkFilename參數指定的是除入口文件外的chunk(這些chunk一般是因爲webpack對代碼的優化所造成的,好比因應實際運行的狀況來異步加載)的命名。

各類Loader配置:module參數

webpack的核心實際上也只能針對js進行打包,那webpack一直號稱可以打包任何資源是怎麼一回事呢?原來,webpack擁有一個相似於插件的機制,名爲Loader,經過Loader,webpack可以針對每一種特定的資源作出相應的處理。Loader的種類至關多,有些比較基礎的是官方本身開發,而其它則是由webpack社區開源貢獻出來的,這裏是Loader的List:list of loaders
而module正是配置什麼資源使用哪一個Loader的參數(由於就算是同一種資源,也可能有不一樣的Loader可使用,固然不一樣Loader處理的手段不同,最後結果也天然就不同了)。module參數有幾個子參數,可是最經常使用的天然仍是loaders子參數,這裏也僅對loaders子參數進行介紹。

loaders參數

loaders參數又有幾個子參數,先給出一個官方示例:

module.loaders: [
  {
    // "test" is commonly used to match the file extension
    test: /\.jsx$/,

    // "include" is commonly used to match the directories
    include: [
      path.resolve(__dirname, "app/src"),
      path.resolve(__dirname, "app/test")
    ],

    // "exclude" should be used to exclude exceptions
    // try to prefer "include" when possible

    // the "loader"
    loader: "babel-loader"
  }
]

下面一一對這些子參數進行說明:

  • test參數用來指示當前配置項針對哪些資源,該值應是一個條件值(condition)。
  • exclude參數用來剔除掉須要忽略的資源,該值應是一個條件值(condition)。
  • include參數用來表示本loader配置僅針對哪些目錄/文件,該值應是一個條件值(condition)。這個參數跟test參數的效果是同樣的(官方文檔也是這麼寫的),我也不明白爲嘛有倆一樣規則的參數,不過咱們姑且能夠本身來劃分這二者的用途:test參數用來指示文件名(包括文件後綴),而include參數則用來指示目錄;注意同時使用這二者的時候,其實是and的關係。
  • loader/loaders參數,用來指示用哪一個/哪些loader來處理目標資源,這倆貨表達的實際上是一個意思,只是寫法不同,我我的推薦用loader寫成一行,多個loader間使用!分割,這種形式相似於管道的概念,又或者說是函數式編程。形如loader: 'css?!postcss!less',能夠很明顯地看出,目標資源先經less-loader處理事後將結果交給postcss-loader做進一步處理,而後最後再交給css-loader。

條件值(condition)能夠是一個字符串(某個資源的文件系統絕對路徑),能夠是一個函數(官方文檔裏是有這麼寫,但既沒有示例也沒有說明,我也是醉了),能夠是一個正則表達式(用來匹配資源的路徑,最經常使用,強烈推薦!),最後,還能夠是一個數組,數組的元素能夠爲上述三種類型,元素之間爲與關係(既必須同時知足數組裏的全部條件)。須要注意的是,loader是能夠接受參數的,方式相似於URL參數,形如'css?minimize&-autoprefixer',具體每一個loader接受什麼參數請參考loader自己的文檔(通常也就只能在github裏看了)。

添加額外功能:plugins參數

這plugins參數至關於一個插槽位(類型是數組),你能夠先按某個plugin要求的方式初始化好了之後,把初始化後的實例丟到這裏來。

示例代碼

諸位看本系列文章,搭配我在Github上的腳手架項目食用更佳哦(笑):Array-Huang/webpack-seed(https://github.com/Array-Huang/webpack-seed)
本文提到的全部內容,均可以在示例代碼根目錄下的webpack.config.js裏找到對應的內容(不過可能稍微有點複雜呢,畢竟是一個能夠投入生產環境的架構了,不過看過我後續的文章,就會以爲很簡單的啦哈哈哈哈)。

附系列文章目錄(同步更新)

本文首發於 Array_Huang的技術博客—— 實用至上,非經做者贊成,請勿轉載。
原文地址: http://www.javashuo.com/article/p-eihwhadk-kg.html
若是您對本系列文章感興趣,歡迎關注訂閱這裏: https://segmentfault.com/blog/array_huang
相關文章
相關標籤/搜索