zoukankan      html  css  js  c++  java
  • Webpack 多页面打包通用方案 动态获取entry

    多页面应用 MPA

    多页面相对于单页面而言,多页面拥有多个入口,一个页面就是一个业务
    单页面所有的业务都在一个url中,只不过后面的hash会发生变化

    多页面应用的优势

    1. 每个页面之间相互解耦
    2. 对于seo更加友好

    多页面打包思路

    一般方案

    每个页面对应一个entry以及html-webpack-plugin
    缺点是每次新增或删除页面需要改webpack配置

    更优方案

    动态获取entry和html-webpack-plugin数量

    通过glob库,利用glob.sync,把目录放在src下的分类目录,命名统一用index.js格式

    1. 把模板文件和相关目录分好类,模板文件名都改成index.js
    /src/*/index.js
    
    1. 安装glob
    npm i glob@7.1.4 -D
    
    1. 动态读取指定文件夹下的文件名
    const entryFiles = glob.sync(path.join(__dirname, './src/*/index.js'))
    
    1. 配置webpack
    'use strict';
    
    const path = require('path');
    const glob = require('glob')
    
    // 将css commonjs 抽成css文件
    const MiniCssExtractPlugin = require('mini-css-extract-plugin')
    // 压缩css文件
    const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin')
    // 压缩html,有几个入口就对应几个html
    const HtmlWebpackPlugin = require('html-webpack-plugin')
    // 每次构建的时候自动清除之前的dist目录下的文件
    const CleanWebpackPlugin = require('clean-webpack-plugin')
    
    const setMPA = () => {
        const entry = {}
        const HtmlWebpackPlugins = []
        const entryFiles = glob.sync(path.join(__dirname, './src/*/index.js'))
        Object.keys(entryFiles).map(index => {
            
            const entryFile = entryFiles[index]
            
            const match =  entryFile.match(/src/(.*)/index.js/)
            const pageName = match && match[1]
            entry[pageName] = `./src/${pageName}/index.js`
            
            HtmlWebpackPlugins.push(new HtmlWebpackPlugin({
                // html模板所在路径
                template: path.join(__dirname, `src/${pageName}/index.html`),
                // 指定输出文件名称
                filename: `${pageName}.html`,
                // 使用哪个chunk生成html页面
                chunks: [pageName],
                // 为true时,jscss会自动注入此html中来
                inject: true,
                // 处理换行,空格,注释
                minify: {
                    html5: true,
                    collapseWhitespace: true,
                    preserveLineBreaks: false,
                    minifyCSS: true,
                    minifyJS: true,
                    removeComments: false
                }
            }))
        })
    
        return {
            entry,
            HtmlWebpackPlugins
        }
    }
    
    const { entry, HtmlWebpackPlugins } = setMPA()
    
    module.exports = {
        // 生产模式还是开发模式
        mode: 'production',
        // 入口 指定入口文件
        entry,
        // 出口 
        output: {
            // 指定输出目录
            path: path.join(__dirname, 'dist'),
            filename: '[name]_[chunkhash:8].js'
        },
        // 配置loader
        module: {
            rules: [
                {
                    test: /.js$/,
                    use: 'babel-loader'
                },
                {
                    test: /.css$/,
                    use: [
                        MiniCssExtractPlugin.loader,
                        // 'style-loader', // 再将样式插入到style标签中
                        'css-loader' // 将css转换成commonjs
                    ]
                },
                {
                    test: /.less$/,
                    use: [
                        MiniCssExtractPlugin.loader,
                        // 'style-loader', // 再将样式插入到style标签中
                        'css-loader', // 将css转换成commonjs
                        'less-loader', // 将less文件转换成css文件
                        // 自动补齐css3前缀
                        {
                            loader: 'postcss-loader',
                            options: {
                                plugins: () => [
                                    require('autoprefixer')(
                                        { browsers: ['last 2 version', '>1%', 'ios 7'] }
                                    )
                                ]
                            }
                        },
                        // px2rem-loader 移动端适配
                        {
                            loader: 'px2rem-loader',
                            options: {
                                remUnit: 75, // 1rem对应75px,10rem对应750px,适合750px视觉稿
                                remPrecision: 8 // px转rem后,小数点的位数
                            }
                        }
                    ]
                },
                {
                    test: /.(png|jpg|gif|jpeg)$/,
                    use: [
                        {
                            loader: 'file-loader',
                            // 图片指纹
                            options: {
                                name: '[name]_[hash:8].[ext]'
                            }
                            // loader: 'url-loader',
                            // options: {
                            //     limit: 40 * 1024 // 40k
                            // }
                        }
                    ]
                },
                {
                    test: /.(woff|woff2|eot|ttf|otf|otf)$/,
                    use: [
                        {
                            loader: 'file-loader',
                            options: {
                                name: '[name]_[hash:8].[ext]'
                            }
                        }
                    ]
                }
            ]
        },
        plugins: [
            // css使用contenthash,避免css没变js变化的时候,css的hash值页随着发布一起变化
            new MiniCssExtractPlugin({
                filename: '[name]_[contenthash:8].css',
            }),
            // 压缩css文件
            new OptimizeCssAssetsPlugin({
                assetNameRegExp: /.css$/g,
                // css预处理器
                cssProcessor: require('cssnano')
            }),
            // 自动清除dist目录下的文件
            new CleanWebpackPlugin()
        ].concat(HtmlWebpackPlugins)  // 压缩html
    }
    

    package.json

    {
      "version": "1.0.0",
      "description": "",
      "main": "index.js",
      "scripts": {
        "test": "echo "Error: no test specified" && exit 1",
        "build": " webpack --config webpack.prod.js ",
        "watch": "webpack --watch",
        "dev": "webpack-dev-server --config webpack.dev.js --open"
      },
      "keywords": [],
      "author": "",
      "license": "ISC",
      "devDependencies": {
        "@babel/core": "^7.4.4",
        "@babel/preset-env": "^7.4.4",
        "@babel/preset-react": "^7.0.0",
        "autoprefixer": "^9.5.1",
        "babel-loader": "^8.0.5",
        "css-loader": "^2.1.1",
        "cssnano": "^4.1.10",
        "file-loader": "^3.0.1",
        "glob": "^7.1.4",
        "html-webpack-plugin": "^3.2.0",
        "less": "^3.9.0",
        "less-loader": "^5.0.0",
        "mini-css-extract-plugin": "^0.6.0",
        "optimize-css-assets-webpack-plugin": "^5.0.1",
        "postcss-loader": "^3.0.0",
        "px2rem-loader": "^0.1.9",
        "raw-loader": "^0.5.1",
        "react": "^16.8.6",
        "react-dom": "^16.8.6",
        "style-loader": "^0.23.1",
        "url-loader": "^1.1.2",
        "webpack": "^4.31.0",
        "webpack-cli": "^3.3.2",
        "webpack-dev-server": "^3.3.1"
      },
      "dependencies": {
        "lib-flexible": "^0.3.2"
      }
    }
    
  • 相关阅读:
    tf.nn.embedding_lookup函数的用法
    windows+python3.6下安装fasttext+fasttext在win上的使用+gensim(fasttext)
    阅读关于DuReader:百度大规模的中文机器阅读理解数据集
    End to End Sequence Labeling via Bidirectional LSTM-CNNs-CRF论文小结
    《Applying Deep Learning to Answer Selection: A Study And an Open Task》文章理解小结
    Windows下基于python3使用word2vec训练中文维基百科语料(三)
    Windows下基于python3使用word2vec训练中文维基百科语料(二)
    Java并发编程:CountDownLatch、CyclicBarrier和 Semaphore
    cpu满问题分析
    Zookeeper用来干什么?
  • 原文地址:https://www.cnblogs.com/ltfxy/p/15328237.html
Copyright © 2011-2022 走看看