少许修改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作一些处理便可,改动并不算太多吧!

相关文章
相关标签/搜索