一直是使用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文件夹中还有子文件夹构成的子页面,这里暂时没有处理,后面会加上。