少許修改webpack配置支持打包多頁面

webpack通常是配合單頁面應用使用,但並非全部的web應用都是單頁的,有多個頁面的狀況仍是不少的,固然你能夠用其它的構建工具來打包,但對於習慣了webpack的你來講,要是能直接在webpack上作少量配置就能夠支持多頁面的打包構建,豈不樂哉!javascript

準備工做

  • webpack已安裝
  • webpack-dev-server已配置
  • js、css、圖片、字體等的loader都已配置完畢

多頁HTML處理

既然是多頁面,也就是說有多個HTML頁面須要處理,並且得根據對應的HTML頁面,打包對應頁面的業務邏輯代碼。好比咱們最後想要的打包目錄結構是這樣的:
imagecss

咱們有三個頁面,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目錄做以下組織:
imagejquery

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作一些處理便可,改動並不算太多吧!

相關文章
相關標籤/搜索