在最開始接觸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