webpackを使用した複数のhtmlファイル


89

私はそれが可能かどうかわからないプロジェクトで何かをしようとしています、私は間違った方法であるか、何かを誤解しています。私たちはwebpackを使用しており、アイデアは複数のhtmlファイルを提供することです。

localhost:8181-> index.htmlを提供します
localhost: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>

誰かが私が間違っていることを知っていますか?

ありがとうございました。


あなたはこれに対する解決策を見つけることができますか?私も同じユースケースを探しています。
モニカ2017年

回答:


124

javascriptモジュール、画像、テンプレートなどの他の多くのアセットを参照するツリーのルートとしてエントリポイントを参照してください。複数のエントリポイントを定義する場合、基本的にアセットをいわゆるチャンクに分割して、すべてのコードとアセットを1つのバンドルにまとめないようにします。

達成したいと思うのは、エントリポイントですでに定義したアセットのさまざまなチャンクも参照する、さまざまなアプリ用の複数の「index.html」を用意することです。

index.htmlファイルをコピーしたり、これらのエントリポイントへの参照を使用してファイルを生成したりすることは、エントリポイントメカニズムでは処理されません。その逆です。htmlページを処理するための基本的なアプローチは、html-webpack-pluginhtmlファイルをコピーできるだけでなく、テンプレートを作成するための広範なメカニズムを備えたを使用することです。これは、アプリを更新するときにブラウザーのキャッシュの問題を回避するために、バンドルにバンドルハッシュの接尾辞を付ける場合に特に役立ちます。

名前パターンを定義した[id].bundle_[chunkhash].jsので、javascriptバンドルはmain.bundle.js、のような名前で呼ばれるため、参照できなくなりますmain.bundle_73efb6da.js

見ていたHTML-WebPACKの-プラグインを。特にユースケースに関連します:

あなたはおそらく最終的にそのようなものを持っているはずです(警告:テストされていません)

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

チャンク配列のエントリポイントの名前を参照することに注意してください。したがって、この例では、これは次のようになります。 exampleEntry。。おそらく、テンプレートをルートsrcフォルダー内に直接配置するのではなく、特定のフォルダーに移動することもお勧めします。

お役に立てれば。


4
良い説明ですが、プロジェクトで作成するさまざまなページごとに「新しいHTMLWebPlugin」を呼び出さなければならないのは気になります。
klewis

誰もが各ページを「新しいHTMLWebPlugin」と呼ぶのは好きではありません。代替が必要です。
ChosenUser

4

HtmlWebpackPluginの使用で複数のHTMLファイルをWebpack使用するには

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ファイルの名前が同じであることを確認してください(上記のコードはそれを前提としています)。


これは良いアプローチでした。ES6構文を使用していますが。こちらをご覧ください
robev

3

2つの異なるビルドが必要ない場合、つまり、同じで異なるHTMLを提供したいだけの場合は、Copy WebpackPluginを使用することもできます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
htmlファイル自体にスクリプト参照を直接与える代わりに、CopyWebpackPluginを使用してbundle.jsファイルをwebpackを介してhtmlファイルに追加する他の方法はありますか?
Sritam Jagadev 2018

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を対応する出力フォルダーにコピーします。


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

このコードは、テンプレートがたくさんある場合に役立ちます:)

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.