在Webpack中配置多个页面的正确方法是什么?

fdx2calv  于 2023-01-30  发布在  Webpack
关注(0)|答案(2)|浏览(162)

我尝试创建一个基本的网站只使用Webpack。我的目的是有一个简单的网址结构,如example.com/about,example.com/contact。
在Webpack中,我可以使用HTMLWebpackPlugin,但我需要为每条路线创建一个示例。因此,我的问题是:有没有办法简化这个问题?

const path = require('path');
const htmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
    entry: './src/main.js',
    output: {
        filename: 'bundle.js',
        path: path.resolve(__dirname, 'dist'),
    },
    devServer: {
        port: 5000,
    },
    plugins: [
        new htmlWebpackPlugin({
            title: 'Home',
            filename: 'index.html',
            template: './src/pages/home/index.html',
        }),
        new htmlWebpackPlugin({
            title: 'About',
            filename: 'about/index.html',
            template: './src/pages/about/index.html',
        }),
    ],
};
7vhp5slm

7vhp5slm1#

Webpack的配置文件是javascript,所以你可以添加一些辅助函数来抽象这个过程,最后只要插入一个页面数组就可以产生预期的效果:

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

const generateHtmlPlugin = (title) => {
  return new htmlWebpackPlugin({
    title,
    filename: 'index.html',
    template: `./src/pages/${title.toLowerCase()}/index.html`,
  });
}

const populateHtmlPlugins = (pagesArray) => {
  res = [];
  pagesArray.forEach(page => {
    res.push(generateHtmlPlugin(page));
  })
  return res;
}

因此,这不是太多的代码,它将允许您在设置webpack时插入您想要的页面数组:

const pages = populateHtmlPlugins(["About", "Articles", "Users", "Contact"]);

module.exports = {
  //...
  plugins: pages
}

更好的是,您可以创建一个utils文件夹,并将代码重构为两个导出的模块,然后只需将populateHtmlPlugins()导入到您的webpack配置文件中,并保持非常干净。
现在,您可以轻松地创建任意数量的页面。

ajsxfq5m

ajsxfq5m2#

在2023年可以使用新的html-bundler-webpack-plugin。使用这个插件,入口点是一个HTML模板,应该加载所有源脚本和样式。
您可以直接在Webpack条目中轻松定义多个HTML模板,例如:

const path = require('path');
const HtmlBundlerPlugin = require('html-bundler-webpack-plugin');

module.exports = {
  output: {
    path: path.join(__dirname, 'dist/'),
  },

  entry: {
    // define HTML templates here
    index: './src/pages/home/index.html',  // => dist/index.html
    'about/index': './src/pages/about/index.html', // => dist/about/index.html
  },

  plugins: [
    new HtmlBundlerPlugin({
      js: {
        // output filename of extracted JS from source script loaded in HTML via `<script>` tag
        filename: 'assets/js/[name].[contenthash:8].js',
      },
      css: {
        // output filename of extracted CSS from source style loaded in HTML via `<link>` tag
        filename: 'assets/css/[name].[contenthash:8].css',
      },
    }),
  ],

  module: {
    rules: [
      {
        test: /\.html$/,
        loader: HtmlBundlerPlugin.loader, // HTML loader
      },
      // styles
      {
        test: /\.(css|sass|scss)$/,
        use: ['css-loader', 'sass-loader'],
      },
      // images
      {
        test: /\.(png|jpe?g|svg|ico)/,
        type: 'asset/resource',
        generator: {
          filename: 'assets/img/[name].[hash:8][ext]',
        },
      },
    ],
  },

  // enable HMR with live reload
  devServer: {
    static: {
      directory: path.join(__dirname, 'dist'),
    },
    watchFiles: {
      paths: ['src/**/*.*'],
      options: {
        usePolling: true,
      },
    },
  },
};

或者您可以生成一个Webpack条目,如上面的答案所示。
例如,index.html

<!DOCTYPE html>
<html
<head>
    <title>Home</title>
    <!-- load source style in HTML, not import in JavaScript -->
    <link href="./style.scss" rel="stylesheet">
    <!-- load source script in HTML, not in Webpack entry -->
    <script src="./main.js" defer="defer"></script>
</head>
<body>
    <h1>Home</h1>
    <!-- load source image -->
    <img src="./image.png">
</body>
</html>

生成的HTML:

<!DOCTYPE html>
<html
<head>
    <title>Home</title>
    <link href="assets/css/style.f57966f4.css" rel="stylesheet">
    <script src="assets/js/main.b855d8f4.js" defer="defer"></script>
</head>
<body>
    <h1>Home</h1>
    <img src="assets/img/image.d2f4b855.png">
</body>
</html>

HtmlBundlerPlugin插件取代了html-webpack-plugin和mini-css-extract-plugin插件最常用的功能。

相关问题