前端臨牀手札——webpack構建逐步解構(上)

前言

因爲博主最近又閒下來了,以前以爲webpack的官方文檔比較難啃一直放到如今。細心閱讀多個webpack配置案例後以爲仍是得本身寫個手腳架,固然這個案例是基於vue的,可是並不影響你使用其餘庫(jquery這些)。文章會逐步分析每一個處理的用意(固然是博主本身的理解),不足之處歡迎指出溝通交流。css

案例

一個通用簡單的手腳架,只需修改簡單配置就可以使用,同時知足多頁面需求。html

multiple-page-vue-webpack-example前端

最近添加了雪碧圖功能,並把sass-loader替換成postcsspress,詳細能夠看分支developvue

使用

# 安裝依賴
$ npm i

# 運行本地服務,訪問 http://localhost:6002 進行開發調試
$ npm run dev

# 構建發行版本到./dist目錄
$ npm run build

目錄結構

build/         #構建配置目錄
src/           #源代碼目錄
    clients/   #入口文件
    imports/   #js代碼目錄,此爲js引入的root目錄
    styles/    #全局樣式目錄
    templates/ #頁面模板文件(建議和入口文件名字對應)

分析案例

乍看案例build目錄下代碼挺多的,並且不少剛入手webpack的人都會瞬間懵逼。可是若是逐步分析理解後就會發覺其實還挺簡單易懂,下面先介紹一下每一個文件做用。html5

/build
    build.js               #構建生產代碼
    config.js              #配置
    dev-client.js 
    dev-server.js          #執行本地服務器
    utils.js               #額外的通用方法
    webpack.base.conf.js   #默認的webpack配置
    webpack.dev.conf.js    #本地開發的webpack配置
    webpack.prod.conf.js   #構建生產的webpack配置

工做流程

clipboard.png

本地測試

結合上面流程圖和build目錄下的文件介紹能看出主要webpack本地測試創建在webpackexpress兩個工具上面。node

首先咱們執行下面代碼,能獲得一個測試服務器,並能在瀏覽器預覽到咱們的代碼效果jquery

$ npm run dev

打開package.json 找到scripts能看到實際執行的是webpack

$ node build/dev-server.js

接下來就先從dev-server.js開始分析git

打開dev-server.js能看到引用這些核心依賴github

  1. ./config

  2. ./webpack.dev.conf

  3. webpack

  4. express

  5. webpack-dev-middleware

  6. webpack-hot-middleware

  7. connect-history-api-fallback

前兩個是配置文件,webpackexpress就不用多說了,主要看剩下那三個。

webpack-dev-middleware

webpack-dev-middleware 是一個結合了webpack配置的express中間件插件(不熟悉express的能夠看這裏),哪他都幹了些什麼呢?官方文檔是這樣說的:

  • 這是一個簡單webpack中間件。它提供一個鏈接服務器並處理訪問webpack中的文件。

  • webpack中的文件寄存在內存,不會生成文件。

  • 若是在觀測模式下修改的文件,中間件再也不提供舊包,但會延遲請求,直到編譯完成,在文件變化後頁面刷新以前你無需等待。

簡單來講就是提供一個可讓你訪問通過webpack處理後的服務,而後看一下dev-server.js下這塊的代碼

const compiler = webpack(webpackConfig)

const devMiddleware = require('webpack-dev-middleware')(compiler, {
  publicPath: '/', 
  stats: {
    colors: true,
    chunks: false
  }
})

compiler就是webpack實例,而後這裏的說明一下publicPath實際上是訪問的目錄根,若是改成/app/那麼你訪問的地址就必須是http://localhost:6002/app/index.html

webpack-hot-middleware

使用它的目的是讓代碼變化時能更新代碼而無需刷新整個頁面,可是這塊配置就較爲繁瑣。除了須要在express掛載這個中間件以外還得修改webpack配置。

首先得在每一個入口前加上webpack-hot-middleware/client,還須要添加一下pluginwebpack配置

// 這塊因爲是多入口處理有點不一樣,後續解析多入口問題和爲什麼使用'./build/dev-client'而不是'webpack-hot-middleware/client'
Object.keys(webpackConfig.entry).forEach(function (name) {
  webpackConfig.entry[name] = ['./build/dev-client'].concat(webpackConfig.entry[name])
})

plugins: [
    ...
    // webpack 1.0
    new webpack.optimize.OccurrenceOrderPlugin(),
    // webpack 2.0
    new webpack.HotModuleReplacementPlugin(),
    new webpack.NoErrorsPlugin()
    ...
]

看到這類估計你會有所疑問,爲什麼入口加上的是./build/dev-client而不是webpack-hot-middleware/client?由於這裏因爲使用了html-webpack-plugin而當修改了html咱們須要它整個頁面刷新,而寫了個簡單的處理,具體能夠看dev-client.js,至於其餘配置細節能夠看官方文檔

connect-history-api-fallback

這個很少說一筆帶過,就是讓你的單頁面路由處理更天然(好比vue-router的mode設置爲html5時),具體看官方文檔

關於多頁面處理

這裏頁面處理使用了html-webpack-plugin插件處理,至於配置須要看三個地方,首先是入口配置webpack.base.conf.js

let webpackConfig = {
    entry: utils.getEntry(config.entry),
    ...
}

因爲使用固定目錄結構的關係,原理就是把src/clients/目錄下的文件都視爲入口文件加載到配置。

還有模板處理webpack.dev.conf.js

webpackConfig.plugins = [].concat(webpackConfig.plugins, utils.htmlLoaders(config.template, webpackConfig.entry))

模板處理也是同樣,這裏創建與一個潛規則:入口文件必須和模板文件的目錄結構和名字一致

在這樣的條件下,多頁面處理就簡單不少了,具體細節可看utils@getEntry()utils@htmlLoaders()。關於html-webpack-plugin配置細節可看官方文檔

後續將會補上構建生產的配置分析,案例參考:vue-cli

前端臨牀手札——webpack構建逐步解構(下)

相關文章
相關標籤/搜索