阿里云主机折上折
  • 微信号
您当前的位置:网站首页 > 多页面应用打包配置

多页面应用打包配置

作者:陈川 阅读数:32393人阅读 分类: 构建工具

多页面应用打包配置的基本概念

多页面应用(MPA)与单页面应用(SPA)的主要区别在于每个页面都有独立的HTML文件。Webpack需要为每个入口文件生成对应的输出文件。典型的MPA项目结构可能如下:

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

配置多入口文件

Webpack配置的核心是定义多个入口点。每个页面对应一个入口文件:

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')
  }
};

处理HTML模板

使用html-webpack-plugin为每个页面生成HTML文件:

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

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

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

优化公共代码提取

使用SplitChunksPlugin提取公共依赖:

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

处理静态资源

配置静态资源加载器:

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]'
        }
      }
    ]
  }
};

开发服务器配置

配置webpack-dev-server支持多页面:

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' }
      ]
    }
  }
};

环境变量配置

区分开发和生产环境:

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'
  }
};

自动化页面发现

动态发现页面目录,避免手动配置:

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处理方案

配置独立的CSS文件:

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'
    })
  ]
};

构建性能优化

配置缓存和并行处理:

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()
    ]
  }
};

多页面路由配置

为生产环境配置路由重定向:

// 在服务器配置中添加(以Express为例)
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'));
});

高级配置技巧

实现页面特定的配置覆盖:

// 在页面目录中添加webpack.config.js
const pageConfig = {
  // 页面特定配置
};

// 在主配置中合并
module.exports = merge(baseConfig, pageConfig);

部署策略

配置不同的部署方案:

// 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

前端川

前端川,陈川的代码茶馆🍵,专治各种不服的Bug退散符💻,日常贩卖秃头警告级的开发心得🛠️,附赠一行代码笑十年的摸鱼宝典🐟,偶尔掉落咖啡杯里泡开的像素级浪漫☕。‌