webpack多页面开发实践

写在前面

在最开始接触webpack的时候,我都觉得webpack只适用于单页面应用,比如webpack+react,webpack+vue。我自己在使用webpack+vue构建项目及开发的过程中感受到了webpack的强大和方便。基于实际项目需求,我在想,多页面站点是否也能使用webapck来构建呢?于是就开始了一番探索,最终算是搭建了一套比较完整的解决方案。

本文以一个实际项目为例子,讲述在多页面项目中如何使用webpack进行工程化构建。本文是自己的实践经验总结,所以有些解决方案并不是最优的,仍在探索优化中,如果有什么错误纰漏,欢迎指出。

简介

本项目主要基于webpack2.x构建,以gulp作为辅助工具。前端使用art-template作为模板引擎,一个页面对应一个模板文件和一个入口文件,入口文件中可以通过importrequire引入其他模块,这些模块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配置

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, 比如

entry: {
    'page-1': '/../webpack-multipage-demo/src/static/js/services/page-1.js'
}
热更新

热更新简直不要太好用,极大地提高了开发效率。

//服务器配置
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,即可实现热更新。

生成html配置

约定同一页面的js文件与模板文件命名一致,最终根据该js生成与其同名的html文件。


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即可。具体实践可参考demo

存在问题

  1. 每新建一个页面就需要重新启动webpack服务

  2. 字体文件无法压缩,对于压缩通过font-face引入的网络字体,目前没有找到较好的解决方案

demo

基于本文理论的一个demo,地址:webpack-multipage-demo

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值