webpack通常是配合單頁面應用使用,但並非全部的web應用都是單頁的,有多個頁面的狀況仍是不少的,固然你能夠用其它的構建工具來打包,但對於習慣了webpack的你來講,要是能直接在webpack上作少量配置就能夠支持多頁面的打包構建,豈不樂哉!javascript
既然是多頁面,也就是說有多個HTML頁面須要處理,並且得根據對應的HTML頁面,打包對應頁面的業務邏輯代碼。好比咱們最後想要的打包目錄結構是這樣的:css
咱們有三個頁面,login.html、index.html、crop.html,咱們分別打包出對應的css文件login.css、index.css、crop.css,且js也是如此的打包,能夠看一下最後輸出的index.html:html
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>index-page</title> <link href="/css/index.css" rel="stylesheet"> </head> <body> <header><nav></nav></header> <div class="container-fluid index-page"> <div class="ocr-wrapper"> <div class="jumbotron"> <h1>Hello World!</h1> <p>這是一個多頁面的webpack配置demo</p> </div> </div> </div> <footer class="footer"></footer> <script type="text/javascript" src="/js/vendors.min.js"></script><script type="text/javascript" src="/js/index.min.js"></script> </body> </html>
index.html自動插入對應的index.css、index.min.js和公共庫代碼vendors.min.js。java
爲了實現這個目的,咱們把咱們的src目錄做以下組織:jquery
template文件夾中放置html的模板頁面,這裏配合html-withimg-loader還能夠實現模板的拆分:webpack
<!DOCTYPE html> <html> <head> #include("./layout/meta.html") <title>crop-page</title> </head> <body> #include("./layout/header.html") <div class="container-fluid"> <div class="ocr-wrapper"> <div class="jumbotron"> <img src="../imgs/picture.jpg" alt="Picture" draggable="false"> </div> </div> </div> #include("./layout/footer.html") </body> </html>
view文件夾則放置每一個頁面的入口文件,在入口文件里加載一些必要的資源:web
import $ from 'jquery'; import 'bootstrap'; import 'bootstrap/dist/css/bootstrap.min.css'; import '../css/index.css'; $(function () { console.log('index page'); });
根據咱們的目錄結構,咱們須要一個方法來獲得entry和文件的對應關係,咱們引入模塊blob
,實現以下方法:npm
// 獲取指定路徑下的入口文件 function getEntries(globPath) { var files = glob.sync(globPath), entries = {}; files.forEach(function(filepath) { // 取倒數第二層(view下面的文件夾)作包名 if(filepath.match(/\.js$/)){ var split = filepath.split('/'); var fileName = split[split.length - 1]; var name = fileName.substring(0, fileName.length - 3); entries[name] = './' + filepath; } }); return entries; }
而後dev模式下,咱們須要在entry裏設置dev-server和hot-reload,因此咱們配置裏的entry應該是一個數組,同時,咱們還得爲每個html頁面都插入對應的資源:bootstrap
var entries = getEntries('src/view/**'); webpackConfig.entry.push('webpack-dev-server/client?http://0.0.0.0:8090'); webpackConfig.entry.push('webpack/hot/only-dev-server'); Object.keys(entries).forEach(function(name) { // 每一個頁面生成一個entry,若是須要HotUpdate,在這裏修改entry webpackConfig.entry.push(entries[name]); // 每一個頁面生成一個html var plugin = new HtmlWebpackPlugin({ // 生成出來的html文件名 filename: name + '.html', // 每一個html的模版,這裏多個頁面使用同一個模版 template: './src/template/'+ name +'.html', // 自動將引用插入html inject: true }); webpackConfig.plugins.push(plugin); });
prod模式下,咱們的entry應該是一個對象,併爲每一個入口添加註入對應的資源,由此咱們得做以下配置:數組
var entries = getEntries('src/view/**'); Object.keys(entries).forEach(function(name) { webpackConfig.entry[name] = entries[name]; // 每一個頁面生成一個html var plugin = new HtmlWebpackPlugin({ // 生成出來的html文件名 filename: name + '.html', // 每一個html的模版,這裏多個頁面使用同一個模版 template: './src/template/'+ name +'.html', // 自動將引用插入html inject: true, // 每一個html引用的js模塊,也能夠在這裏加上vendor等公用模塊 chunks: ['vendors', name] }); webpackConfig.plugins.push(plugin); }); webpackConfig.entry['vendors'] = ['jquery', 'bootstrap'];
這樣,咱們的多頁面配置就搞定了,只需在單頁的基礎上,對entry作一些處理便可,改動並不算太多吧!