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