使用webpack的多个html文件

pod7payv  于 2022-12-27  发布在  Webpack
关注(0)|答案(7)|浏览(220)

我正在尝试做一个项目,我不知道是否可能,我在一个错误的方式或误解的东西。我们正在使用webpack,和想法是服务于一个以上的html文件。
本地主机:8181-〉服务于index.html
本地主机:8181/示例. html-〉服务于示例. html
我尝试通过设置多个入口点来实现,遵循documentation
文件夹结构为:

/
|- 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="/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="/style/default.css">
</head>
<body>
    ...
    <script src="/example.bundle.js"></script>
</body>
</html>

有人知道我哪里做错了吗?
谢谢你。

3duebb1j

3duebb1j1#

把一个入口点看作是一棵树的根,它引用了许多其他的资产,比如javascript模块,图片,模板等等,当你定义了不止一个入口点时,你基本上把你的资产分割成所谓的块,而不是把你所有的代码和资产放在一个单独的包里。
我认为您想要实现的是为不同的应用程序提供多个"index.html",这些应用程序还引用您已经用入口点定义的资产的不同块。
复制一个index.html文件,甚至生成一个引用这些入口点的文件,都不是由入口点机制来处理的,而是相反的,处理html页面的一个基本方法是使用html-webpack-plugin,它不仅可以复制html文件,而且有一个扩展的模板机制。如果您想让您的捆绑包带有一个捆绑包哈希后缀,以避免在更新应用时出现浏览器缓存问题,这一点尤其有用。
因为你已经定义了一个命名模式为[id].bundle_[chunkhash].js,所以你不能再用main.bundle.js来引用你的javascript包,因为它将被称为main.bundle_73efb6da.js
看看html-webpack-plugin,它与您的用例特别相关:

  • 生成多个html文件
  • 过滤块

最后你可能应该有这样的东西(警告:未测试)

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文件夹中,这可能也是一个好主意。

1l5u6lss

1l5u6lss2#

使用 HtmlWebpackPluginWebpack中使用 * 多个HTML* 文件:

通过直接嵌入以下代码修改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文件具有相同的名称(上面的代码假设)。

xam8gpfp

xam8gpfp3#

如果您不需要两个不同的构建版本,也可以使用Copy Webpack Plugin,即假设您只想用相同的main.bundle.js提供不同的HTML。
这个插件非常简单(只在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>
irlmq6kh

irlmq6kh4#

RICHARD ABRAHAM的解决方案对我来说效果很好,我还添加了检测HTML文件的fsreaddir函数

let htmlPageNames = [];
const pages = fs.readdirSync('./src')
pages.forEach(page => {
    if (page.endsWith('.html')) {
        htmlPageNames.push(page.split('.html')[0])
    }
})
console.log(htmlPageNames);
wwtsj6pe

wwtsj6pe5#

还有另一个解决方案,假设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复制到相应的 output 文件夹。

izkcnapc

izkcnapc6#

plugins: [
  ...templates.map(template => new HtmlWebpackPlugin(template))
]

如果您有很多模板,此代码会有所帮助:)

qmb5sa22

qmb5sa227#

返回到@andreas-jägle point。使用'html-webpack-plugin':html-webpack-plugin html-webpack-plugin。但是优化您的代码以避免文件的重复

plugins: ['index', 'page1', 'page2'].map(
    (file) =>
      new HtmlWebpackPlugin({
        template: './src/' + file + '.html',
        inject: true,
        chunks: ['index', 'main'],
        filename: './' + file + '.html' //relative to root of the application
      })
  )

相关问题