使用webpack的多个HTML文件


87

我正在尝试在某个项目中做某事,但不确定是否可行,我做错了什么或误解了某件事。我们正在使用webpack,其想法是提供多个html文件。

本地主机:8181->提供index.html
本地主机:8181 / example.html->提供example.html

我正在尝试通过遵循文档设置多个入口点来做到这一点:

文件夹结构为:

/
|- package.json
|- webpack.config.js
  /src
   |- index.html
   |- example.html
   | /js
      |- main.js
      |- example.js

Webpack.config.js:

...
entry: {
    main: './js/main.js',
    exampleEntry: './js/example.js'
},
output: {
    path: path.resolve(__dirname, 'build', 'target'),
    publicPath: '/',
    filename: '[name].bundle.js',
    chunkFilename: '[id].bundle_[chunkhash].js',
    sourceMapFilename: '[file].map'
},
...

index.html

<!DOCTYPE html>
<html
<head>
    ...
    <link type="text/css" href="https://stackoverflow.com/style/default.css">
</head>
<body>
    <div id="container"></div>
    <script src="/main.bundle.js"></script>
</body>
</html>

example.html:

<!DOCTYPE html>
<html
<head>
    ...
    <link type="text/css" href="https://stackoverflow.com/style/default.css">
</head>
<body>
    ...
    <script src="/example.bundle.js"></script>
</body>
</html>

有人知道我做错了吗?

谢谢。


您能找到解决方案吗?我也在寻找相同的用例。
monica

Answers:


118

将入口点视为树的根,该树引用了许多其他资产,例如javascript模块,图像,模板等。当定义多个入口点时,基本上是将资产分成所谓的大块,以使所有代码和资产都不会放在一个捆绑中。

我认为您想要实现的是为不同的应用程序提供多个“ index.html”,这些应用程序还引用了您已经使用入口点定义的资产的不同部分。

复制index.html文件,甚至生成带有对这些入口点的引用的文件都不由入口点机制处理-相反。处理html页面的基本方法是使用,html-webpack-plugin它不仅可以复制html文件,而且具有广泛的模板化机制。如果您想为捆绑包添加捆绑包散列后缀,这在避免更新应用程序时避免浏览器缓存问题,则特别有用。

定义了名称模式后,[id].bundle_[chunkhash].js您将无法再引用javascript包,main.bundle.js因为它将被称为main.bundle_73efb6da.js

看看html-webpack-plugin。与您的用例特别相关:

最后,您可能应该有类似的内容(警告:未经测试)

plugins: [
  new HtmlWebpackPlugin({
    filename: 'index.html',
    template: 'src/index.html',
    chunks: ['main']
  }),
  new HtmlWebpackPlugin({
    filename: 'example.html',
    template: 'src/example.html',
    chunks: ['exampleEntry']
  })
]

请注意在chunks数组中引用入口点的名称,因此在您的示例中,该名称应为exampleEntry。最好将模板移到特定文件夹中,而不要直接将其放在根src文件夹中。

希望这可以帮助。


4
很好的解释,但仍然令我困扰,您必须为在项目中创建的每个不同页面调用“ new HTMLWebPlugin”。
klewis

每个人都不喜欢每个页面都称为“新HTMLWebPlugin”。需要替代。
ChosenUser

3

如果不需要两个不同的版本,也可以使用“复制Webpack插件”,即,假设您只想使用相同的HTML提供不同的HTML main.bundle.js

该插件确实非常简单(仅在webpack v4中进行了测试):

const CopyWebpackPlugin = require('copy-webpack-plugin');

const config = {
  plugins: [
    new CopyWebpackPlugin([
      { from: './src/example.html', to: './example.html' }
    ])
  ]
}

然后,example.html您可以从中加载构建index.html。例如:

<!DOCTYPE html>
<html
<head>
    ...
    <title>Example</title>
</head>
<body>
    <div id="container"> Show an example </div>
    <script src="main.bundle.js"></script>
</body>
</html>

1
还有其他方法可以使用CopyWebpackPlugin并通过webpack将bundle.js文件添加到html文件中,而不是直接在html文件本身中提供脚本引用吗?
Sritam Jagadev

3

要使用多个HTML文件中Webpack使用HtmlWebpackPlugin

webpack.config.js通过直接嵌入以下代码来修改。

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

let htmlPageNames = ['example1', 'example2', 'example3', 'example4'];
let multipleHtmlPlugins = htmlPageNames.map(name => {
  return new HtmlWebpackPlugin({
    template: `./src/${name}.html`, // relative path to the HTML files
    filename: `${name}.html`, // output HTML files
    chunks: [`${name}`] // respective JS files
  })
});

module.exports = {
  entry: {
    main: './js/main.js',
    example1: './js/example1.js',
    //... repeat until example 4
  },
  module: { 
       //.. your rules
  };
  plugins: [
    new HtmlWebpackPlugin({
      template: "./src/index.html",
      chunks: ['main']
    })
  ].concat(multipleHtmlPlugins)
  
};

您可以根据需要向htmlPageNames阵列添加任意数量的HTML页面。确保每个HTML和相应的JS文件都具有相同的名称(以上代码假定该名称)。


0

假设Webpack ^ 4.44.1,还有另一种解决方案。也就是说,在您的JS / TS应用程序中导入HTML。

样本webpack.config.js

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');


module.exports = {
    entry: { app: './src/index.ts' },

    mode: 'development',
    devtool: 'inline-source-map',
    plugins: [
        new CleanWebpackPlugin(),
        new HtmlWebpackPlugin({
            title: 'Development',
            template: path.join(path.resolve(__dirname, 'src'), 'index.ejs')
        }),
    ],
    module: {
        rules: [
            {
                test: /\.ts$/,
                use: 'ts-loader',
                include: [path.resolve(__dirname, 'src')],
                exclude: /node_modules/,
            },
            {
                test: /\.html$/i,
                use: [
                    {
                        loader: 'file-loader',
                        options: {
                            name: '[name].[ext]'
                        }
                    }
                ],
                // this exclude is required
                exclude: path.join(path.resolve(__dirname, 'src'), 'index.html')
            }
        ],
    },
    resolve: {
        extensions: ['.ts', '.js'],
    },
    devServer: {
        contentBase: path.join(__dirname, 'dist'),
        compress: true,
        port: 3900
    },
    output: {
        filename: 'bundle.js',
        path: path.resolve(__dirname, 'dist'),
    },
};

对应的应用

import './about.html';
    
console.log('this is a test'); 

index.ejs

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Question</title>
</head>
<body>
     <a href="./about.html">About</a>
</body>
</html>

about.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>About</title>
</head>
<body>
    <p>This is an about page</p>
</body>
</html>

Webpack会将about.html复制到相应的输出文件夹。


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.