一直是使用vue官方提供的腳手架工具來作開發單頁應用,突發奇想的想作一個多頁應用的打包配置,順便了解一下webpack的使用。花了幾天時間搞定以後才發現了這篇文章《進階| Vue 2.x + Webpack 3.x + Nodejs 多頁面項目框架(上篇)》。但仍是要記錄一下本身搭建的過程。代碼地址:https://github.com/lzy1043/webpack-multiple-pages。css
build目錄下是webpack的配置文件
src/components目錄下是通用的組件
src/views下是應用的頁面html
打包前多頁面的目錄結構:vue
打包以後的生成的項目結構:node
代碼裏面的ESlint和babel的配置是直接使用的vue-cli中的配置。webpack
多頁應用就表明着須要有多個入口,webpack的entry支持多入口,使用entry的對象語法對每一個頁面設置入口。相似下面這種寫法:git
entry: { home: "./home.js", about: "./about.js", contact: "./contact.js" }
可是咱們這裏須要使用node的fs模塊來取得全部須要進行配置的頁面。github
能夠看到這裏有四個頁面index,home,about和news,而後每個頁面中都有一個模板文件,一個入口js文件,其實這裏的html模板文件均可以使用同一個,後面會作一些修改。每一個目錄下還應該有一個根vue組件。好比index目錄下的app.vue。web
config/index.js :生成多頁面的入口配置vue-cli
首先,讀取多頁面目錄,找出其中須要配置入口的頁面express
// 設置基礎目錄 const baseDir = path.resolve(__dirname, '../src/views') // excludeDir 是用來配置忽略哪些文件夾,不生成入口文件,這裏因爲index打包後的目錄有些特殊須要單獨設置 const excludeDir = ['index'] // 取到全部頁面,目錄名稱 const viewArr = fs.readdirSync(baseDir).filter(dir => { return excludeDir.indexOf(dir) === -1 && fs.statSync(baseDir + '/' + dir).isDirectory() })
首頁的入口配置:
let entriesConfig = [{ entryName: 'index', entry: path.resolve(baseDir, 'index/index.js'), filename: 'index.html', template: path.resolve(baseDir, 'index.html') }]
而後對取出的頁面作遍歷生成入口名稱,入口配置,模板名稱,模板路徑
viewArr.forEach(dir => { // 入口文件 const enrtyFile = dir + '.js' // 模板文件名稱, const filename = dir + '/' + dir + '.html' entriesConfig.push({ //入口名稱 entryName: dir, //入口文件 entry: path.resolve(baseDir, dir, enrtyFile), // 打包生成的模板名稱,若是filename包含路徑信息會建立對應的路徑 //好比about這個頁面左後打包的結果是: /dist/about/about.html filename: filename, //html模板的路徑 template: path.resolve(baseDir, filename) }) })
最後將入口的配置
module.exports = entriesConfig
這樣多頁面的入口配置就完成了,下面就須要配置webpack開發環境的打包環境的配置了。
首先是作了一個基礎的配置,包括入口和module,module.rules這一塊使用的也是vue-cli生成的項目全部的配置,不作過多的贅述,直接看代碼。
// webpack.base.conf.js const path = require('path') const entriesConfig = require('../config') let entries = {} entriesConfig.forEach(item => { entries[item.entryName] = item.entry }) module.exports = { entry: entries, resolve: { extensions: ['.js', '.vue', '.json'], alias: { 'vue$': 'vue/dist/vue.esm.js', '@': path.resolve(__dirname, '../src') } }, module: { rules: [ { test: /\.(js|vue)$/, loader: 'eslint-loader', enforce: 'pre', include: [path.resolve(__dirname, 'src')], options: { formatter: require('eslint-friendly-formatter') } }, { test: /\.vue$/, loader: 'vue-loader', options: { loaders: { scss: 'vue-style-loader!css-loader!sass-loader', sass: 'vue-style-loader!css-loader!sass-loader?indentedSyntax' } } }, { test: /\.js$/, loader: 'babel-loader', include: [path.resolve(__dirname, '../src')] }, { test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, loader: 'url-loader', options: { limit: 10000, name: path.posix.join('static', 'img/[name].[hash:7].[ext]') } } ] } }
其次,開發環境下主要是須要配置一個熱更新的部分,這部分也是參考了vue-cli中的配置, 使用express + webpack-dev-middleware + webpack-hot-middleware。使用的方法webpack中講的也很清楚,你們能夠本身看一下,我把連接貼在這:
最後就是打包的配置,在打包的匹配值中須要注意的一點就是須要根據生成的入口文件中的filename和template自動生成對應的頁面,可使用html-webpack-plugin來生成。其他的配置都和vue的單頁應用相似。
//部分代碼 entriesConfig.forEach(item => { const option = { filename: item.filename, template: item.template, chunks: ['vendor', item.entryName] } webpackConfig.plugins.push(new HtmlWebpackPlugin(option)) })
差很少就是這些。
沒有考慮子頁面,好比在news文件夾中還有子文件夾構成的子頁面,這裏暫時沒有處理,後面會加上。