多页面打包配置

作者: 泡杯感冒灵 | 来源:发表于2020-03-25 15:10 被阅读0次

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

    什么叫做单页面应用呢?
    • 整个应用里边只有一个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

    相关文章

      网友评论

        本文标题:多页面打包配置

        本文链接:https://www.haomeiwen.com/subject/vkvtuhtx.html