vue多页面应用配置

目录结构

使用vue-cli 3.0构建

${root}/
    build/
        utils.js
    public/
        index.html
    src/
        assets/
            css/
            img/
        components/
            index.js
        pages/
            list/
                index.html
                index.js
                index.vue
            details/
                index.html
                index.js
                index.vue
        utils/
        store.js
    ......
    vue.confug.js

主要代码

src/page/*/inedx.html


  
    
    
    
    
    
    
    
    
    友帮
    <% for (var chunk in htmlWebpackPlugin.files.css) { %>
        <% if(htmlWebpackPlugin.files.css[chunk]) {%>
            
        <%}%>
    <% } %>
  
  
    
<% for (var chunk in htmlWebpackPlugin.files.js) { %> <% if(htmlWebpackPlugin.files.js[chunk]) {%> <%}%> <% } %>
src/page/*/inedx.js
import Vue from 'vue'
import App from './index.vue'
import store from '@/store';

new Vue({
  store,
  render: h => h(App)
}).$mount('#app')

build/utils.js
const path = require('path')

// glob是webpack安装时依赖的一个第三方模块,还模块允许你使用 *等符号,
// 例如lib/*.js就是获取lib文件夹下的所有js后缀名的文件
const glob = require('glob')

// 取得相应的页面路径,因为之前的配置,所以是src文件夹下的pages文件夹
const PAGE_PATH = path.resolve(__dirname, '../src/pages')

// 用于做相应的merge处理
const merge = require('webpack-merge')

const HtmlWebpackPlugin = require('html-webpack-plugin')

// 多入口配置
// 通过glob模块读取page文件夹下的所有对应文件夹下的js后缀文件,如果该文件存在
// 那么就作为入口处理
exports.getEntries = () => {
    let entryFiles = glob.sync(PAGE_PATH + '/*/index.js')
    let map = {}

    entryFiles.forEach(filePath => {
        var _path = filePath.substring(0,filePath.lastIndexOf('\/index.'))
        var filename = _path.substring(_path.lastIndexOf('\/')+1)
        map[filename] = filePath
    })

    return map
}


// 多页面输出配置
// 与上面的多页面入口配置相同,读取page文件夹下的对应的html后缀文件,然后放入数组中
exports.htmlPlugin = configs => {
    let entryHtml = glob.sync(PAGE_PATH + '/*/index.html')
    let arr = []

    entryHtml.forEach(filePath => {
        var _path = filePath.substring(0,filePath.lastIndexOf('\/index.'))
        var filename = _path.substring(_path.lastIndexOf('\/')+1)

        let conf = {
            multihtmlCache: true,
            // 模板来源
            template: filePath,
            // 文件名称
            filename: filename + '.html',
            // 页面模板需要加对应的js脚本,如果不加这行则每个页面都会引入所有的js脚本
            // chunks: ['manifest', 'vendor',  filename],
            chunks: ['chunk-vendors', 'chunk-common', filename],
            inject: false,
        }

        if (configs) {
            conf = merge(conf, configs)
        }

        if (process.env.NODE_ENV === 'production') {
            conf = merge(conf, {
                minify: {
                    removeComments: true, // 删除html中的注释代码
                    collapseWhitespace: true, // 删除html中的空白符
                },
                chunksSortMode: 'manual'// 按manual的顺序引入
            })
        }
        arr.push(new HtmlWebpackPlugin(conf))
    })

    return arr
}

// pages 多入口配置
exports.setPages = configs => {
    let entryFiles = glob.sync(PAGE_PATH + '/*/index.js');
    let map = {};

    entryFiles.forEach(filePath => {
        var _path = filePath.substring(0,filePath.lastIndexOf('\/index.'))
        var filename = _path.substring(_path.lastIndexOf('\/')+1)

        let tmp = _path+'/'+filename;

        let conf = {
            // page 的入口
            entry: filePath, 
            // 模板来源
            template: tmp + '.html', 
            // 在 dist/index.html 的输出
            filename: filename + '.html', 
            // 页面模板需要加对应的js脚本,如果不加这行则每个页面都会引入所有的js脚本
            // chunks: ['manifest', 'vendor', filename], 
            chunks: ['chunk-vendors', 'chunk-common', filename], 
            inject: false,
        };

        if (configs) {
            conf = merge(conf, configs)
        }

        if (process.env.NODE_ENV === 'production') {
            conf = merge(conf, {
                minify: {
                    removeComments: true, // 删除html中的注释代码
                    collapseWhitespace: true, // 删除html中的空白符
                },
                chunksSortMode: 'manual'// 按manual的顺序引入
            })
        }

        map[filename] = conf;
    })

    return map
}
vue.confug.js
const path = require('path')
const utils = require('./build/utils')

// 用于做相应的merge处理
const merge = require('webpack-merge')

const resolve = dir => {
    return path.join(__dirname, dir)
}
module.exports = {
    // 项目二级目录
    publicPath: './',
    // 编译输出目录
    outputDir: resolve('../../../build/app/module'),
    // 生产环境构建生成 source map
    productionSourceMap: true,
    chainWebpack: config => {
        config.module
            .rule('images')
            .use('url-loader')
            .tap(options =>
                merge(options, {
                  limit: 5120,
                })  
            )
        config.resolve.alias
            .set('@', resolve('src'))
            .set('@img', resolve('src/assets/img'))
    },
    // 本地服务器
    devServer: {
        open: true, // 是否自动打开浏览器页面
        // ......
    },
    // 多入口
    configureWebpack: config => {
        config.entry = utils.getEntries() // 直接覆盖 entry 配置
        
        // 使用 return 一个对象会通过 webpack-merge 进行合并,plugins 不会置空
        return {
            plugins: [...utils.htmlPlugin()]
        }
    },
    // pages 多入口配置
    pages: utils.setPages(),
}

编译之后的目录

${root}/
    css/
        chunk-common.xxx.css
        chunk-vendors.xxx.css
        list.xxx.css
        details.xxx.css
    img/
        image.xxx.png
        ......
    js/
        chunk-common.xxx.js
        chunk-vendors.xxx.js
        list.xxx.js
        details.xxx.js
    list.html
    details.html

你可能感兴趣的:(vue多页面应用配置)