阿里云主机折上折
  • 微信号
Current Site:Index > Multi-page application packaging configuration

Multi-page application packaging configuration

Author:Chuan Chen 阅读数:32392人阅读 分类: 构建工具

Basic Concepts of Multi-Page Application (MPA) Bundling Configuration

The main difference between a Multi-Page Application (MPA) and a Single-Page Application (SPA) is that each page in an MPA has its own independent HTML file. Webpack needs to generate corresponding output files for each entry file. A typical MPA project structure might look like this:

project/
├── src/
│   ├── pages/
│   │   ├── home/
│   │   │   ├── index.js
│   │   │   └── index.html
│   │   ├── about/
│   │   │   ├── about.js
│   │   │   └── about.html
│   │   └── contact/
│   │       ├── contact.js
│   │       └── contact.html
├── public/
└── webpack.config.js

Configuring Multiple Entry Files

The core of Webpack configuration is defining multiple entry points. Each page corresponds to an entry file:

const path = require('path');

module.exports = {
  entry: {
    home: './src/pages/home/index.js',
    about: './src/pages/about/about.js',
    contact: './src/pages/contact/contact.js'
  },
  output: {
    filename: '[name].bundle.js',
    path: path.resolve(__dirname, 'dist')
  }
};

Handling HTML Templates

Use html-webpack-plugin to generate HTML files for each page:

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

const pages = ['home', 'about', 'contact'];

module.exports = {
  // ...other configurations
  plugins: pages.map(page => new HtmlWebpackPlugin({
    template: `./src/pages/${page}/${page}.html`,
    filename: `${page}.html`,
    chunks: [page]
  }))
};

Optimizing Common Code Extraction

Use SplitChunksPlugin to extract common dependencies:

module.exports = {
  optimization: {
    splitChunks: {
      chunks: 'all',
      cacheGroups: {
        vendor: {
          test: /[\\/]node_modules[\\/]/,
          name: 'vendors',
          chunks: 'all'
        }
      }
    }
  }
};

Handling Static Assets

Configure static asset loaders:

module.exports = {
  module: {
    rules: [
      {
        test: /\.(png|jpe?g|gif|svg)$/i,
        type: 'asset/resource',
        generator: {
          filename: 'images/[name][ext]'
        }
      },
      {
        test: /\.(woff|woff2|eot|ttf|otf)$/i,
        type: 'asset/resource',
        generator: {
          filename: 'fonts/[name][ext]'
        }
      }
    ]
  }
};

Development Server Configuration

Configure webpack-dev-server to support multiple pages:

module.exports = {
  devServer: {
    static: {
      directory: path.join(__dirname, 'dist'),
    },
    port: 8080,
    historyApiFallback: {
      rewrites: [
        { from: /^\/home/, to: '/home.html' },
        { from: /^\/about/, to: '/about.html' },
        { from: /^\/contact/, to: '/contact.html' }
      ]
    }
  }
};

Environment Variable Configuration

Differentiate between development and production environments:

const isProduction = process.env.NODE_ENV === 'production';

module.exports = {
  mode: isProduction ? 'production' : 'development',
  devtool: isProduction ? 'source-map' : 'eval-cheap-module-source-map',
  output: {
    filename: isProduction ? '[name].[contenthash].js' : '[name].js'
  }
};

Automated Page Discovery

Dynamically discover page directories to avoid manual configuration:

const fs = require('fs');
const pages = fs.readdirSync(path.join(__dirname, 'src/pages'));

const entry = {};
const htmlPlugins = [];

pages.forEach(page => {
  entry[page] = `./src/pages/${page}/index.js`;
  htmlPlugins.push(new HtmlWebpackPlugin({
    template: `./src/pages/${page}/index.html`,
    filename: `${page}.html`,
    chunks: [page]
  }));
});

module.exports = {
  entry,
  plugins: [...htmlPlugins]
};

CSS Processing Solution

Configure standalone CSS files:

const MiniCssExtractPlugin = require('mini-css-extract-plugin');

module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/i,
        use: [
          isProduction ? MiniCssExtractPlugin.loader : 'style-loader',
          'css-loader',
          'postcss-loader'
        ]
      }
    ]
  },
  plugins: [
    new MiniCssExtractPlugin({
      filename: 'css/[name].[contenthash].css'
    })
  ]
};

Build Performance Optimization

Configure caching and parallel processing:

const TerserPlugin = require('terser-webpack-plugin');
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');

module.exports = {
  cache: {
    type: 'filesystem',
    buildDependencies: {
      config: [__filename]
    }
  },
  optimization: {
    minimizer: [
      new TerserPlugin({
        parallel: true,
        terserOptions: {
          compress: {
            drop_console: true
          }
        }
      }),
      new CssMinimizerPlugin()
    ]
  }
};

Multi-Page Routing Configuration

Configure route redirection for production environments:

// Add to server configuration (using Express as an example)
app.get('/', (req, res) => {
  res.sendFile(path.join(__dirname, 'dist', 'home.html'));
});

app.get('/about', (req, res) => {
  res.sendFile(path.join(__dirname, 'dist', 'about.html'));
});

app.get('/contact', (req, res) => {
  res.sendFile(path.join(__dirname, 'dist', 'contact.html'));
});

Advanced Configuration Techniques

Implement page-specific configuration overrides:

// Add webpack.config.js in the page directory
const pageConfig = {
  // Page-specific configurations
};

// Merge in the main configuration
module.exports = merge(baseConfig, pageConfig);

Deployment Strategies

Configure different deployment solutions:

// webpack.deploy.config.js
module.exports = {
  output: {
    publicPath: process.env.CDN_URL || '/'
  },
  plugins: [
    new WebpackPluginUpload({
      bucket: 'my-bucket',
      region: 'us-east-1',
      accessKeyId: process.env.AWS_ACCESS_KEY,
      secretAccessKey: process.env.AWS_SECRET_KEY
    })
  ]
};

本站部分内容来自互联网,一切版权均归源网站或源作者所有。

如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn

Front End Chuan

Front End Chuan, Chen Chuan's Code Teahouse 🍵, specializing in exorcising all kinds of stubborn bugs 💻. Daily serving baldness-warning-level development insights 🛠️, with a bonus of one-liners that'll make you laugh for ten years 🐟. Occasionally drops pixel-perfect romance brewed in a coffee cup ☕.