webpack多页面配置

项目目录结构如下:

config文件夹内代码如下:

  index.js:

  

module.exports = {
    dev: {
        assetsSubDirectory: 'static',
        assetsPublicPath: '',
        devtool: 'cheap-module-eval-source-map',
        proxy: {
            '/api': {
                target: 'http://localhost:8888',
                changeOrigin: true,
                pathRewrite: {
                    '^/api': '/api'
                }
            }
        },
        // host: 'localhost',
        host:'0.0.0.0',
        port: 8888
    },
    prod: {
        assetsSubDirectory: 'static',
        assetsPublicPath: './',
        devtool: 'source-map'
    },
    templatePc(data) {  //PC sprite template
        return data.sprites.map(sprite => {
            return (
`.icon-${sprite.name} {
     ${sprite.px.width};
    height: ${sprite.px.height};
    background: url(${sprite.image}) ${sprite.px.offset_x} ${sprite.px.offset_y} no-repeat;
    background-size: ${sprite.px.total_width} ${sprite.px.total_height};       
}
`)
        }).join('')
    },
    templateWeb(data) {  //WEB sprite template
        return data.sprites.map(sprite => {
            return (
`.icon-${sprite.name} {
     ${sprite.width}pr;
    height: ${sprite.height}pr;
    background: url(${sprite.image}) ${sprite.offset_x}pr ${sprite.offset_y}pr no-repeat;
    background-size: ${sprite.total_width}pr ${sprite.total_height}pr;       
}
`)
        }).join('')
    }
}

utils.js内代码如下:

const glob = require('glob')
// const path = require('path')
exports.getEntry = function () {
  const entry = {}
  // 读取src目录所有page入口
  glob.sync('../src/pages/*/*.js').forEach((name) => {
    const start = name.indexOf('src/') + 4;
    const end = name.length - 3;
    const eArr = [];
    const n = name.slice(start, end).split('/')[1];
    eArr.push(name);
    // eArr.push('@babel/polyfill'); // 引入这个,是为了用async await,一些IE不支持的属性能够受支持,兼容IE浏览器用的
    entry[n] = eArr;
  })
  return entry;
}
exports.getEntry2 = function (globPath) {
    var entries = {}, tmp, pathname
  
    glob.sync(globPath).forEach(function (entry) {
      tmp = entry.split('/').splice(-3)
      pathname = tmp.splice(1, 1).toString().toLowerCase()
      entries[pathname] = entry
    })
    return entries
  }

webpack.config.base.js:

const path = require('path')
const config = require('./index')
const SpritesmithPlugin = require('webpack-spritesmith')
const utils = require('./utils')

function resolve(dir) {
    return path.join(__dirname, '..', dir);
}
// const { getEntry } = require('./utils.js')
module.exports = {
    context: path.resolve(__dirname, '../'),
    // entry:getEntry(),
    entry: utils.getEntry2("./src/pages/*/main.js"),
    // entry: {
    //     main: './src/main.js'
    // },
    // entry:{
    //     index:'./src/pages/index/main.js',
    //     test:'./src/pages/test/main.js'
    // },
    output: {
        path: path.resolve(__dirname, '../dist'),
        filename: '[name].js',
        publicPath: process.env.NODE_ENV === 'production'
        ? config.prod.assetsPublicPath
        : config.dev.assetsPublicPath
    },
    resolve: {
        extensions: ['.js', '.json', 'jsx'],
        alias: {
            '@': resolve('src'),
            '@static': resolve('static')
        },
        modules: ['node_modules', resolve('src/assets/images')]
    },
    module: {
        rules: [
            {
                test: /.jsx?$/,
                use: [
                    {
                        loader: 'babel-loader',
                        options: {
                            cacheDirectory: true
                        }
                    }, {
                        loader: 'eslint-loader',
                        options: {
                            formatter: require('eslint-friendly-formatter')
                        }
                    }
                ],
                exclude: [resolve('node_modules')],
                include: [resolve('src')]
            },
            // {
            //     test: /.html$/,
            //     loader: 'html-loader'
            // },
            {
                test: /.(png|jpe?g|gif|svg)(?.*)?$/,
                loader: 'url-loader',
                options: {
                    limit: 10000,
                    name: 'images/[name]_[hash:8].[ext]'
                }
            },
            {
                test: /.(mp4|webm|ogg|mp3|wav|flac|aac)(?.*)?$/,
                loader: 'url-loader',
                options: {
                    limit: 10000,
                    name: 'media/[name]_[hash:8].[ext]'
                }
            },
            {
                test: /.(woff2?|eot|ttf|otf)(?.*)?$/,
                loader: 'url-loader',
                options: {
                    limit: 100000,
                    name: 'fonts/[name]_[hash:8].[ext]'
                }
            }
        ]
    },
    plugins: [
        new SpritesmithPlugin({
            src: {
                cwd: resolve('src/assets/images/icons'),
                glob: '*.png'
            },
            target: {
                image: resolve('src/assets/images/sprite.png'),
                css: [
                    [resolve('src/assets/scss/_sprite.scss'), {
                        format: 'based_template'
                    }]
                ]
            },
            customTemplates: {
                'based_template': config.templateWeb
            },
            apiOptions: {
                cssImageRef: '../images/sprite.png'
            },
            spritesmithOptions: {
                algorithm: 'top-down', //'top-down', 'left-right', 'diagonal', 'alt-diagonal', 'binary-tree'
                padding: 10
            }
        })
    ],
    externals: {
        jquery: 'jQuery',
        swiper: 'Swiper'
    }
}

webpack.config.base.js:

const path = require('path')
const config = require('./index')
const webpackBaseConfig = require('./webpack.config.base')
const webpack = require('webpack')
const merge = require('webpack-merge')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const FriendlyErrorsWebpackPlugin = require('friendly-errors-webpack-plugin')
const notifier = require('node-notifier')
const portfinder = require('portfinder')
const utils = require('./utils')

var pages = utils.getEntry2('./src/pages/**/index.html');
var htmls = [];
Object.keys(pages).forEach(name => {

  var templateUrl = pages[name];

  var templateThunks = [name]
  htmls.push(new HtmlWebpackPlugin({
    filename: name + '.html',
    template: templateUrl, // 模板路径
    inject: true,
    chunks: templateThunks
  }))
})

const webpackDevConfig = merge(webpackBaseConfig, {
    mode: 'development',
    module: {
        rules: [
            {
                test: /.(sa|sc|c)ss$/,
                use: [
                    'style-loader',
                    {
                        loader: 'css-loader',
                        options: {
                            importLoaders: 2,
                            sourceMap: true
                        }
                    },
                    'postcss-loader',
                    'sass-loader'
                ]
            }
        ]
    },
    devtool: config.dev.devtool,
    devServer: {
        contentBase: path.join(__dirname, '../dist'),
        clientLogLevel: 'warning',
        historyApiFallback: true,
        hot: true,
        compress: true,
        host: config.dev.host,
        port: config.dev.port,
        open: true,
        overlay: {
            warnings: true,
            errors: true
        },
        publicPath: config.dev.assetsPublicPath,
        proxy: config.dev.proxy,
        quiet: true
    },
    plugins: [
        new webpack.HotModuleReplacementPlugin(),
        new webpack.NamedModulesPlugin(),
        new webpack.NoEmitOnErrorsPlugin(),
        ...htmls
        // new HtmlWebpackPlugin({
        //     filename: 'index.html',
        //     template: './src/pages/index/index.html',
        //     inject: true,
        //     chunks:["index"]
        // }),
        // new HtmlWebpackPlugin({
        //     filename: 'test.html',
        //     template: './src/pages/test/index.html',
        //     inject: true,
        //     chunks:["test"]
        // })
    ]
})

module.exports = new Promise((resolve, reject) => {
    portfinder.basePort = config.dev.port
    portfinder.getPort((err, port) => {
        if (err) {
            reject(err)
        } else {
            webpackDevConfig.devServer.port = port
            webpackDevConfig.plugins.push(new FriendlyErrorsWebpackPlugin({
                compilationSuccessInfo: {
                    messages: [`You application is running here ${webpackDevConfig.devServer.host}:${port}`]
                },
                onErrors: (severity, errors) => {
                    if (severity !== 'error') {
                        return
                    }
                    const error = errors[0]
                    const filename = error.file && error.file.split('!').pop()
                    notifier.notify({
                        title: error.name,
                        subtitle: filename || '',
                        message: severity + ': ' + error.message
                    });
                }
            }))
            resolve(webpackDevConfig)
        }
    })
})

webpack.config.prod.js:

const path = require('path')
const config = require('./index')
const webpackBaseConfig = require('./webpack.config.base')
const merge = require('webpack-merge')
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
const CopyWebpackPlugin = require('copy-webpack-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin') //extract css
const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin') //compress css
const TerserPlugin = require('terser-webpack-plugin') //compress js
// const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
const utils = require('./utils')

var pages = utils.getEntry2('./src/pages/**/index.html');
var htmls = [];
Object.keys(pages).forEach(name => {

  var templateUrl = pages[name];

  var templateThunks = [name]
  htmls.push(new HtmlWebpackPlugin({
    filename: name + '.html',
    template: templateUrl, // 模板路径
    inject: true,
    chunks: templateThunks
  }))
})

const webpackProdConfig = merge(webpackBaseConfig, {
    mode: 'development',
    output: {
        path: path.resolve(__dirname, '../dist'),
        filename: 'js/[name]_[chunkhash:8].js',
        chunkFilename: 'js/[id]_[chunkhash:8].js',
        publicPath: config.prod.assetsPublicPath
    },
    module: {
        rules: [
            {
                test: /.(sa|sc|c)ss$/,
                use: [
                    {
                        loader: MiniCssExtractPlugin.loader,
                        options: {
                            publicPath: '../'
                        }
                    },
                    {
                        loader: 'css-loader',
                        options: {
                            importLoaders: 2
                        }
                    },
                    'postcss-loader',
                    'sass-loader'
                ]
            },
            {
                test: /.(png|jpe?g|gif|svg)(?.*)?$/,
                loader: 'image-webpack-loader',
                enforce: 'pre'
            }
        ]
    },
    devtool: config.prod.devtool,
    optimization: {
        concatenateModules: true,
        splitChunks: {
            chunks: 'all'
        },
        minimizer: [
            new OptimizeCssAssetsPlugin(),
            new TerserPlugin({
                parallel: true,
                cache: true,
                terserOptions: {
                    compress: {
                        unused: true,
                        drop_debugger: true,
                        drop_console: true,
                        dead_code: true
                    }
                }
            }),
        ],
    },
    plugins: [
        new CleanWebpackPlugin(),
        new MiniCssExtractPlugin({
            filename: 'css/[name]_[contenthash:8].css',
            chunkFilename: 'css/[name]_[contenthash:8].css',
        }),
        new OptimizeCssAssetsPlugin({
            assetNameRegExp: /.optimize.css$/g,
            cssProcessor: require('cssnano'),
            cssProcessorPluginOptions: {
                preset: ['default', { discardComments: { removeAll: true } }],
            },
            canPrint: true
        }),
        ...htmls,
        // new HtmlWebpackPlugin({
        //     filename: '../dist/index.html',
        //     template: 'src/index.html',
        //     inject: true
        // }),
        new CopyWebpackPlugin([{
            from: path.resolve(__dirname, '../static'),
            to: config.dev.assetsSubDirectory,
            ignore: ['.*']
        }]),
        // new BundleAnalyzerPlugin()
    ]
})

module.exports = webpackProdConfig

package.json内script代码

"scripts": {
    "dev": "webpack-dev-server --inline --progress --config config/webpack.config.dev.js",
    "start": "npm run dev",
    "build": "webpack --progress --config config/webpack.config.prod.js"
  },

1、使用第三方库

1.1需要用到第三方库时需在页面引入,比如jq

1.2同时还在配置文件中解析

externals: {
        jquery: 'jQuery',
        swiper: 'Swiper'
    }

1.3最后在页面对应的main.js里使用时采用如下语法

import $ from 'jquery'
$(".close_ly").click(function(){
    $(".leyu_yspd,.toumingbi_yspd").hide()
})
$(".head_onlineChat").click(function(){
    $(".leyu_yspd,.toumingbi_yspd").show()
})

2、引入样式

2.1直接在页面内对应的main.js里

import "@/assets/scss/select.scss"

3、引用组件

3.1在页面内使用

<%= require('html-loader!../../components/header.html') %>
 
注意这是EJS的语法,一定不能使用html-loader(html-loader会将模版以字符串方式解析)
// {
            //     test: /.html$/,
            //     loader: 'html-loader'
            // },

4、图片引入

4.1页面引入图片

<img src="<%= require('../../assets/images/07.png') %>" alt="">
4.2组件内引入图片
<img src="../assets/images/03.png" alt="">
 
原文地址:https://www.cnblogs.com/nanacln/p/11422993.html