在最开始接触webpack的时候,我都以为webpack只适用于单页面应用,好比webpack+react,webpack+vue。我本身在使用webpack+vue构建项目及开发的过程当中感觉到了webpack的强大和方便。基于实际项目需求,我在想,多页面站点是否也能使用webapck来构建呢?因而就开始了一番探索,最终算是搭建了一套比较完整的解决方案。css
本文以一个实际项目为例子,讲述在多页面项目中如何使用webpack进行工程化构建。本文是本身的实践经验总结,因此有些解决方案并非最优的,仍在探索优化中,若是有什么错误纰漏,欢迎指出。html
本项目主要基于webpack2.x构建,以gulp做为辅助工具。前端使用art-template做为模板引擎,一个页面对应一个模板文件和一个入口文件,入口文件中能够经过import
或require
引入其余模块,这些模块webpack会自动跟入口文件合并为一个文件。前端
├─dist #打包后生成的文件目录 └─src #开发目录 ├─components #通用组件 ├─static #静态资源目录 │ ├─css │ ├─img │ └─js │ ├─component #站点通用组件对应的js │ ├─lib #第三方js库 │ ├─services #各页面入口 │ └─util #通用工具js ├─template #html模板 └─views #页面 main.js #公共入口 gulpfile.js #gulp任务配置 package.json #项目依赖 webpack.config.js #webpack配置
// 获取入口文件 var entries = (function() { var jsDir = path.resolve(__dirname, 'src/static/js/services'); var entryFiles = glob.sync(jsDir + '/*.js'); var map = {}; entryFiles.forEach(function(filePath) { var filename = filePath.substring(filePath.lastIndexOf('\/') + 1, filePath.lastIndexOf('.')); map[filename] = filePath; }); return map; })();
该方法将生成文件名到文件绝对路径的map, 好比vue
entry: { 'page-1': '/../webpack-multipage-demo/src/static/js/services/page-1.js' }
热更新简直不要太好用,极大地提升了开发效率。react
//服务器配置 var devServer = env === 'production' ? {} : { contentBase: path.resolve(__dirname), compress: true, historyApiFallback: true, hot: true, inline: true, host: 'localhost', port: 8080 };
另外,在plugin
中加入new webpack.HotModuleReplacementPlugin()
,开启Hot Module Replacemen
,便可实现热更新。webpack
约定同一页面的js
文件与模板文件命名一致,最终根据该js
生成与其同名的html
文件。git
var htmlPages = (function() { var artDir = path.resolve(__dirname, 'src/views'); var artFiles = glob.sync(artDir + '/*.art'); var array = []; artFiles.forEach(function(filePath) { var filename = filePath.substring(filePath.lastIndexOf('\/') + 1, filePath.lastIndexOf('.')); array.push(new HtmlWebpackPlugin({ template: path.resolve(__dirname, 'src/template/index.html'), filename: filename + '.html', chunks: ['vendor', 'main', filename], chunksSortMode: function(chunk1, chunk2) { var order = ['vendor', 'main', filename]; var order1 = order.indexOf(chunk1.names[0]); var order2 = order.indexOf(chunk2.names[0]); return order1 - order2; }, minify: { removeComments: env === 'production' ? true : false, collapseWhitespace: env === 'production' ? true : false } })); }); return array; })();
对于一些在多个页面中都须要用到的模块,可将其提取出来做为通用的组件。组件的构成与页面同样,一个.js
文件和一个.art
文件以及一个.css
文件,在js
文件中渲染html
内容,最后export
,使用时直接require
便可。具体实践可参考demogithub
每新建一个页面就须要从新启动webpack
服务web
字体文件没法压缩,对于压缩经过font-face
引入的网络字体,目前没有找到较好的解决方案json
基于本文理论的一个demo,地址:webpack-multipage-demo