Webpack 從哪兒去到哪兒去

流程

指定一個或多個入口(源碼目錄文件) entry,將各個模塊打包封裝爲一個或多個代碼塊 chunk,並生成文件一個或多個 bundlecss

entry

肯定入口模塊的位置,定義 chunk name,默認爲 main。其形式能夠是:字符串、對象、數組或函數,字符串和數組其 chunk name 沒法改變,只能是默認值。html

字符串入口

module.exports = {
  entry: './src/index.js'
};
複製代碼

數組入口

將多個資源先合併,建過最後一個元素做爲實際的入口路徑。react

module.exports = {
  entry: [
    'babel-polyfill',
    './src/index.js'
  ]
};
複製代碼

上面等同於在 ./src/index.jsimport 'babel-polyfill'webpack

對象入口

定義多個入口時必須使用的形式。其中web

  • 對象的屬性名 key 就是 chunk name;
  • 對象的屬性值 value 就是入口路徑,能夠是字符串,也能夠爲數組;
module.exports = {
  entry: {
    'index': ['babel-polyfill', './src/index.js'],
    'lib': './src/lib.js'
  }
};
複製代碼

函數式入口

只要返回字符串、數組和對象,能夠動態配置,支持返回一個 Promise 對象進行一步操做,自由度很大。數組

module.exports = {
  entry: new Promise((resolve) => {
    // 模擬異步操做
    setTimeout(() => {
      resolve('./src/index.js');
    }, 1000)
  })
};
複製代碼

context

資源入口的路徑前綴,務必使用絕對路徑。其做用是爲了讓 entry 編寫更加簡潔。緩存

module.exports = {
  context: path.join(__dirname, './src'),
  entry: './index.js'
}
複製代碼

提取 vendor

一般,都是由 app.js 單一入口進行引用,這樣就會產生一個 bundle.js 文件,隨着業務擴展,資源體積愈加增大,從而下降用戶的頁面渲染速度。另外,也是因爲只產生一個 bundle.js,因此編碼稍做改動更新,就用從新打包,用戶也要跟着從新下載,友好度不理想。babel

咱們都知道:庫、框架等第三方模塊(只要是非業務模塊)這些幾百年不會變化(誇張手法,意在說明不常改動更新),可集中打包。而後客戶端緩存起來,從而提升用戶界面的渲染速度。react-router

module.exports = {
  entry: {
    app: './src/app.js',
    vendor: ['react', 'react-dom', 'react-router']
  }
};
複製代碼

上面 entry 增長了 chunk name 爲 vendor 這個 key,其 value 是個數組,可是數組中的值路徑並指出,這到底怎麼回事?這個就須要 optimization.splitChunks(webpack4 以前是 CommonsChunkPlugin),將 app 和 vendor 這兩個 chunk 中的模塊提取出來。app

  • app,含業務模塊和第三方依賴模塊;
  • vendor,第三方模塊;

多頁應用

咱們但願的是一個頁面對應一個獨立的 bundle,而不是將全部頁面打包到一個 bundle 中。

module.exports = {
  entry: {
    home: './src/home.js',
    shopCar: './src/shopCar.js',
    order: './src/order.js',
    vendor: ['react', 'react-dom', 'react-router']
  }
}
複製代碼

output

說了這麼多,都是在說資源入口,對於資源出口使用配置 output 對象,其配置項有不少,在此只舉例說明高頻使用的一些屬性配置。

單入口和多入口

1.單入口

module.exports = {
  output: {
    filename: 'bundle.js',
    path: path.join(__dirname, 'assets'),
    publicPath: '/dist'
  }
};
複製代碼

2.多入口

module.exports = {
  entry: {
    app: './src/app.js',
    vendor: './src/vendor.js'
  },
  output: {
    filename: '[name].js'
  }
};
複製代碼

filename

打包後的 bundle 名字,可配合 path,也能夠是一個相對路徑 filename: './src/bundle.js',對於多入口場景能夠 filename: [name].js;

變量名稱 描述 說明
[hash] 指代 webpack 這次打包全部資源生成的 hash 只要 chunk 內容發生變化,就會改變,影響其餘資源
[chunkhash] 指代當前 chunk 內容的 hash 只有當前 chunk 內容發生變化,纔會改變,使用緩存推薦使用
[name] 指代當前 chunk 的 name
[id] 指代當前 chunk 的 id
[query] 指代 filename 配置項中的 query 與 chunk 內容無關,需開發者手動指定

因此上面配置能夠稍做改動

module.exports = {
  entry: {
    app: './src/app.js',
    vendor: './src/vendor.js'
  },
  output: {
    filename: '[name].[chunkhash].js'
  }
};
複製代碼

一般,只有生產環境才配置 [chunkhash],緣由是爲了更新緩存,開發環境無需配置。

path

指定資源文件輸出位置,其值須爲絕對路徑,默認爲 dist 目錄。若是不更改它,可沒必要配置;

publicPath

指定資源請求位置,容易與上面 path 的輸出位置弄混。請求一種來自 HTML 頁面,好比 script 標籤加載,一種來自 js 或 css 請求,加載 js、圖片或字體等。主要有 3 中形式

1.HTML 形式 相對路徑。假設當前 HTML 地址是 http://xxx.com/page/index.html,如今加載 index.js 文件

  • publicPath: '',則 http://xxx.com/page/index.js;
  • publicPath: './js',則 http://xxx.com/page/js/index.js;
  • publicPath: '../assets',則 http://xxx.com/assets/index.js;

2.HOST 形式 相對路徑。設置的值如果以 / 開始,就是基於頁面地址 host name 爲基礎路徑的。假設當前 HTML 地址是 http://xxx.com/page/index.html,如今加載 index.js 文件

  • publicPath: '/',則 http://xxx.com/index.js;
  • publicPath: '/js/',則 http://xxx.com/js/index.js;
  • publicPath: '/assets/',則 http://xxx.com/assets/index.js;

3.CDN 絕對路徑。一般這類資源都是靜態的,因爲靜態資源的域名與當前頁面域名不一致,因此才設置指定絕對路徑。若 public 值以協議頭或相對協議的形式開始,那就說明是與 CDN 相關。

假設當前 HTML 地址是 http://xxx.com/page/index.html,如今加載 index.js 文件

  • publicPath: 'https://cdn.com/',則 https://cdn.com/index.js;
  • publicPath: 'http://cdn.com/',則 http://cdn.com/index.js;
  • publicPath: '//cdn.com/assets/',則 //cdn.com/assets/index.js;

注意,前面咱們介紹的 webpack-dev-server 中也有個 publicPath,比較容易弄混的是 webpack-dev-server 的 publicPath 與 output 的 publicPath沒有關係,卻與 output 的 path 有關係。可看

module.exports = {
  entry: './src/app.js',
  output: {
    filename: 'bundle.js',
    path: path.join(__dirname, 'dist')
  },
  devServer: {
    publicPath: '/assets/',
    port: 1989
  }
};
複製代碼

啓動 webpack-dev-server 服務後,訪問 localhost:1989/dist/bundle.js 則會返回 404,由於 devServer.publicPath 此時設置的路徑是 localhost:1989/assets/,因此訪問 localhost:1989/assets/bundle.js 纔是有效路徑。爲了避免必要引發這類麻煩問題,可將二者輸出默認設置一致。

上一篇:模塊

下一篇:預處理器

相關文章
相關標籤/搜索