產生原因:
目前使用Vue的Web應用越來越多,包括很多手機App都使用Vue來開發前端。但是使用官方的vue-cli webpack僅僅是單頁面,一個大一點的項目一個頁面往往是不夠的。那么vue-cli能不能支持多Html頁面呢?答案是可以的,那就需要我們去改動一下webpack的配置。
簡介:
我把它取了個名字叫做vue-webpack-multipage,顧名思義:vue基於webpack的多頁面框架。我同時會給大家講如何基於官方的vue-cli webpack的demo上改動,也會把我修改過后的demo上傳到git共享給大家(但是不保證模塊是最新的,所以大家最好跟着教程自己配置一下)。在之前呢,我參考了其他大佬的一些方法,然后自己總結了一下,並進行了優化。可以支持多級目錄,至於多少級呢,這個是不限制的,所以個人認為還是比較智能的。本教程涉及到vue-cli原有支持需要你們自己查閱哦。
配置教程:
前置條件:你已經熟悉了vue-cli
1.創建項目
//就是你使用官方vue-cli的用法 vue init webpack 項目名
2.添加多頁面幫助工具:這是封裝的各種多頁面支持的方法,我命名為multipage-helper.js,放在項目的build文件夾下
/** * 多頁面支持 * @File: * @Description: 多頁面支持 * @author qingyi xuelongqy@foxmail.com * @date 2017/6/15 10:16 * @version V1.0 */ var path = require('path') var fs = require("fs") var HtmlWebpackPlugin = require('html-webpack-plugin') var moduleList //緩存多頁面模塊列表 var moduleRootPath = './src/module' //模塊根目錄(這個可以根據自己的需求命名) /** * 獲取js入口數組 */ exports.getEntries = function getEntries(){ //緩存js入口數組 var entries = {} //初始化模塊列表 this.getModuleList() //變量模塊列表 moduleList.forEach(function (module) { if (module.moduleID != "" && module.moduleJS != ""){ entries[module.moduleID] = module.moduleJS } }) console.log("*********************************** entries ***********************************") console.log(entries) return entries } /** * 獲取多頁面模塊列表 * @returns {模塊的信息集合} */ exports.getModuleList = function getModuleList() { //判斷是否為空,不為空則直接返回 if (moduleList){ return moduleList }else {//為空則讀取列表 moduleList = new Array(); readDirSync(moduleRootPath, "") console.log("*********************************** moduleList ***********************************") console.log(moduleList) return moduleList } } /** * 獲取dev的Html模板集合 * @returns {dev的Html模板集合} */ exports.getDevHtmlWebpackPluginList = function getDevHtmlWebpackPluginList(){ console.log("*********************************** devHtmlWebpackPluginList ***********************************") //緩存dev的Html模板集合 var devHtmlWebpackPluginList = [] //獲取多頁面模塊集合 var moduleList = this.getModuleList() //遍歷生成模塊的HTML模板 moduleList.forEach(function (mod) { //生成配置 var conf = { filename: mod.moduleID+".html", template: mod.moduleHTML, chunks: [mod.moduleID], inject: true } console.log(conf) //添加HtmlWebpackPlugin對象 devHtmlWebpackPluginList.push(new HtmlWebpackPlugin(conf)) }) return devHtmlWebpackPluginList } /** * 獲取prod的Html模板集合 * @returns {prod的Html模板集合} */ exports.getProdHtmlWebpackPluginList = function getProdHtmlWebpackPluginList(){ console.log("*********************************** prodHtmlWebpackPluginList ***********************************") //緩存dev的Html模板集合 var prodHtmlWebpackPluginList = [] //獲取多頁面模塊集合 var moduleList = this.getModuleList() //遍歷生成模塊的HTML模板 moduleList.forEach(function (mod) { //生成配置 var conf = { filename: mod.moduleID+".html", template: mod.moduleHTML, inject: true, minify: { removeComments: true, collapseWhitespace: true, removeAttributeQuotes: true // more options: // https://github.com/kangax/html-minifier#options-quick-reference }, // necessary to consistently work with multiple chunks via CommonsChunkPlugin chunksSortMode: 'dependency', chunks: ['manifest','vendor',mod.moduleID] } console.log(conf) //添加HtmlWebpackPlugin對象 prodHtmlWebpackPluginList.push(new HtmlWebpackPlugin(conf)) }) return prodHtmlWebpackPluginList } /** * 深度遍歷目錄,並整理多頁面模塊 * @param path 需要變量的路徑 * @param moduleName 模塊名稱 */ function readDirSync(path,moduleName){ //緩存模塊對象 var module = {moduleID:"",moduleHTML:"",moduleJS:""} //獲取當前模塊ID var moduleID = path.replace(moduleRootPath+"/","") if (path == moduleRootPath){ moduleID = "" } module.moduleID = moduleID //獲取目錄下所有文件及文件夾 var pa = fs.readdirSync(path) pa.forEach(function(ele,index){ var info = fs.statSync(path+"/"+ele) if(info.isDirectory()){ // console.log("dir: "+ele) readDirSync(path+"/"+ele, ele) }else{ //判斷當前模塊的html是否存在 if (moduleName+".html" == ele){ module.moduleHTML = path+"/"+ele } //判斷當前模塊的js是否存在 if (moduleName+".js" == ele){ module.moduleJS = path+"/"+ele } // console.log("file: "+ele) } }) //判斷模塊是否真實(可能只是個分級目錄) if ((module.moduleID != "" && module.moduleHTML != "") || (module.moduleID != "" && module.moduleJS != "")){ moduleList.push(module) } }
3.修改webpack.base.conf.js:配置多個頁面的js入口
//**添加** //引入多頁面支持 var multipageHelper = require('./multipage-helper') //**修改** module.exports = { entry: multipageHelper.getEntries(), //設置入口集合 ... }
4.修改webpack.dev.conf.js:開發時的多頁面模板配置
//**添加** //引入多頁面支持 var multipageHelper = require('./multipage-helper') //**刪除** //刪除module.exports中原有的HtmlWebpackPlugin配置(內容可能不一樣,反正HtmlWebpackPlugin就對了) new HtmlWebpackPlugin({ filename: 'index.html', template: 'index.html', inject: true }) //**末尾添加** //添加Html模板集合 Array.prototype.push.apply(module.exports.plugins,multipageHelper.getDevHtmlWebpackPluginList())
5.修改webpack.prod.conf.js:編譯時的多頁面模板配置
//**添加** //引入多頁面支持 var multipageHelper = require('./multipage-helper') //**刪除** //刪除webpackConfig中原有的HtmlWebpackPlugin配置(內容可能不一樣,反正HtmlWebpackPlugin就對了) new HtmlWebpackPlugin({ filename: config.build.index, template: 'index.html', inject: true, minify: { removeComments: true, collapseWhitespace: true, removeAttributeQuotes: true // more options: // https://github.com/kangax/html-minifier#options-quick-reference }, // necessary to consistently work with multiple chunks via CommonsChunkPlugin chunksSortMode: 'dependency' }) //**末尾添加** //添加Html模板集合 Array.prototype.push.apply(module.exports.plugins,multipageHelper.getProdHtmlWebpackPluginList())
6.目錄結構及其使用:目錄結構有點講究,一說就懂
看圖說話
我把所有的頁面放在了module下,這個呢是可以修改的(multipage-helper.js的moduleRootPath變量)
我用commodity_info來舉例
- commodity_info.js vue的入口文件(以前的main.js)
- commodity_info.html 這就是一個Html頁面(以前的index.html)
- commodity_info.vue vue的視圖文件(以前的App.vue)
其實沒啥好說的,就是每個頁面需要的文件封裝到同一個文件夾內。
需要注意的是:上面三個文件名需要和文件夾名字相同
編譯后文件的路徑:會把整個文件夾的內容打包成一個html。怎么理解呢?我舉個例子就懂了,還是commodity_info,最后會編譯為/commodity/commodity_info.html;如果是resources就是/resources.html;如果是book就是/resources/book.html。So easy!!
多級目錄:通過上面你就知道很人性化的支持了多目錄結構了。它會一個一個目錄去遍歷,查找是否有和目錄名字相同的js、html和vue。
vue-webpack-multipage框架實例源碼:
如果你不太理解怎么用,去看看代碼就知道啦。
項目地址(碼雲):https://git.oschina.net/xuelongqy/vue-webpack-multipage.git
github地址:https://github.com/xuelongqy/vue-webpack-multipage.git
演示地址:http://114.215.136.14/VueMulti/
特別重要:
如果你支持我的話,記得在碼雲上捐贈我哦!!!
如果你有問題,或者想跟我討論,留言吧。也可以到我的微博:http://weibo.com/xuelongqy