搜索
您的当前位置:首页正文

多页面打包配置

来源:哗拓教育

之前我们打包,实际上都是对单页面应用进行的打包

什么叫做单页面应用呢?
  • 整个应用里边只有一个html文件,就是单页面应用;比如我们之前的例子,当我们运行npm run build的时候,dist目录里,只有一个idnex.html
    image.png
  • 现在主流框架,vue,react都是单页面应用,所以webpack做打包的时候,绝大多数场景都是对单页面应用进行打包;但是在一些特殊的场景下,比如兼容一些jquery的老的项目,或者zepto这样的老的项目,包括一些特别奇怪的场景之中,我们确实会遇到要对多页面应用进行打包的场景
那么该怎么实现对多页面应用的打包呢?

之前,我们通过html-webpack-plugin这个插件,打包之后会在dist目录下生成一个index.html文件,并且文件里会引入打包生成的main.js文件

image.png
  • 现在假如我们有另外一个页面list.js,我们希望打包之后,webpack会生成一个list.html文件,而且在list.html文件里只引入打包生成的list.js文件。而原来的index.html文件,只引入main.js文件

    image.png
  • 我们先配置入口文件


    image.png
    image.png
  • 我们可以这样配置html-webpack-plugin,意思是打包的时候,以src目录下的index.html为模板,分别生成一个index.html文件和list.html文件,filenamehtml-webpack-plugin这个插件的属性,更多属性可以到github去查

    image.png
  • 配置好以后,我们再重新打包,可以看到,生成的dist文件夹下,有index.html和list.html文件了


    image.png
  • 但是无论是index.html 还是list.html ,里边都同时引入了main.jslist.js;这不是我们想要的,我们的目标是 index.html文件里引入main.js,而list.html里引入list.js文件

    image.png
  • 针对这种问题,我们该怎么解决呢,我们还可以给html-webpack-plugin再配置一个参数chunks,这个配置的意思是,这个html文件要引入的打包生成的js文件有哪些;其中runtime.jsvenfors.js是两个html文件都需要的

    image.png
  • 配置好后,我们再进行打包,可以看到dist.html出了公用的js文件,只引入了list.js;而 index,html里只引了main.js

    image.png
    image.png
  • 而这两个文件也是可以正常运行的


    image.png
    image.png
经过上边的配置,我们就实现了多页面应用的打包。它的实现方式,实际上就是调整入口文件配置。和配置多个html-webpack-plugin而已
虽然我们上边实现了多页面应用的配置,但是我们是手动的,只有两个页面,如果有很多页面,我们是不是要手动去增加多个入口文件,并且增加多个html-webpack-plugin? 很明显这种方式是效率低下的,有没有方式能智能的帮我们实现这个目标呢?
const path = require('path');
const fs = require('fs');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const AddAssetHtmlWebpackPlugin = require('add-asset-html-webpack-plugin')
const webpack = require('webpack');

// 写一个函数,用来生成 plugins,这个函数接收 confis参数
const makePlugins = (configs) => {
        // 创建一个plugins 数组,初始只有CleanWebpackPlugin 这个插件
    const plugins = [
        new CleanWebpackPlugin(['dist'], {
            root: path.resolve(__dirname, '../')
        })
    ]
        
        // 获取到 configs的entry配置,入口配置有几个key,打包的时候,就生成几个 html文件, 文件名是key值
    Object.keys(configs.entry).forEach(item => {
        plugins.push(
            new HtmlWebpackPlugin({
                template: 'src/index.html',
                filename: `${item}.html`,
                chunks:['runtime','vendors',item]
            })
        )
    })

        // 读取到dll文件夹下的文件,然后遍历,并根据后缀名,使用使用不同的插件
    const files = fs.readdirSync(path.resolve(__dirname, '../dll'));
    files.forEach((file) => {
        if (/.*\.dll.js/.test(file)) {
            plugins.push(
                new AddAssetHtmlWebpackPlugin({
                    filepath: path.resolve(__dirname, '../dll', file)
                })
            )
        }
        if (/.*\.manifest.json/.test(file)) {
            plugins.push(
                new webpack.DllReferencePlugin({
                    manifest: path.resolve(__dirname, '../dll', file)
                })
            )
        }
    })
    return plugins
}





// 把配置复制给一个变量  configs
const configs = {
    entry: {
        index: './src/index.js',
        list: './src/list.js'
    },
    resolve: {
        extensions: ['.js', '.jsx']
    },
    module: {
        rules: [{
            test: /\.jsx?$/,
            include: path.resolve(__dirname, '../src'),
            use: [{
                loader: 'babel-loader'
            }]
        }, {
            test: /\.(jpg|png|gif)$/,
            use: {
                loader: 'url-loader',
                options: {
                    name: '[name]_[hash].[ext]',
                    outputPath: 'images/',
                    limit: 10240
                }
            }
        }, {
            test: /\.(eot|ttf|svg)$/,
            use: {
                loader: 'file-loader'
            }
        }]
    },
    optimization: {
        runtimeChunk: {
            name: 'runtime'
        },
        usedExports: true,
        splitChunks: {
            chunks: 'all',
            cacheGroups: {
                vendors: {
                    test: /[\\/]node_modules[\\/]/,
                    priority: -10,
                    name: 'vendors',
                }
            }
        }
    },
    performance: false,
    output: {
        path: path.resolve(__dirname, '../dist')
    }
}

// 通过makePlugins 函数给 configs的plugins属性赋值
configs.plugins = makePlugins(configs);

// 导出configs
module.exports = configs
通过上边的配置。如果我们再增加页面,值需要在src下新增一个js文件,然后再去入口文件新增一个配置就醒了。
  • 比如我们新增了 detail页面


    image.png
  • 修改entry配置


    image.png
  • 再次打包,生成了detail.html,而且可以正常运行


    image.png
    image.png
Top