webpack多頁面開發實踐

寫在前面

在最開始接觸webpack的時候,我都以爲webpack只適用於單頁面應用,好比webpack+react,webpack+vue。我本身在使用webpack+vue構建項目及開發的過程當中感覺到了webpack的強大和方便。基於實際項目需求,我在想,多頁面站點是否也能使用webapck來構建呢?因而就開始了一番探索,最終算是搭建了一套比較完整的解決方案。css

本文以一個實際項目爲例子,講述在多頁面項目中如何使用webpack進行工程化構建。本文是本身的實踐經驗總結,因此有些解決方案並非最優的,仍在探索優化中,若是有什麼錯誤紕漏,歡迎指出。html

簡介

本項目主要基於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, 好比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

生成html配置

約定同一頁面的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

存在問題

  1. 每新建一個頁面就須要從新啓動webpack服務web

  2. 字體文件沒法壓縮,對於壓縮經過font-face引入的網絡字體,目前沒有找到較好的解決方案json

demo

基於本文理論的一個demo,地址:webpack-multipage-demo

相關文章
相關標籤/搜索