Web paketini kullanan birden çok html dosyası


89

Mümkün olup olmadığından emin olmadığım bir projede bir şeyler yapmaya çalışıyorum, yanlış bir yoldayım veya bir şeyi yanlış anlıyorum. Web paketi kullanıyoruz ve fikir birden fazla html dosyası sunmaktır.

localhost: 8181 -> index.html
localhost: 8181 / example.html'yi sunar -> example.html'yi sunar

Belgelere göre birden çok giriş noktası belirleyerek bunu yapmaya çalışıyorum :

Klasör yapısı:

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

Biri neyi yanlış yaptığımı biliyor mu?

Teşekkür ederim.


Bunun için bir çözüm bulabiliyor musunuz? Ben de aynı kullanım durumunu arıyorum.
monica

Yanıtlar:


124

Javascript modülleri, resimler, şablonlar vb. Gibi diğer birçok varlığa başvuran bir ağacın kökü olarak bir giriş noktası görün. Birden fazla giriş noktası tanımladığınızda, tüm kodunuzu ve varlıklarınızı tek bir pakette bulundurmamak için temel olarak varlıklarınızı sözde parçalara bölersiniz.

Başarmak istediğinizi düşündüğüm şey, giriş noktalarınızla zaten tanımladığınız varlıklarınızın farklı parçalarına da atıfta bulunan farklı uygulamalar için birden fazla "index.html" ye sahip olmaktır.

Bir index.html dosyasını kopyalamak veya hatta bu giriş noktalarına referanslarla bir tane oluşturmak, giriş noktası mekanizması tarafından ele alınmaz - tam tersidir. Html sayfalarını işlemek için temel bir yaklaşım, html-webpack-pluginyalnızca html dosyalarını kopyalayabilen değil, aynı zamanda şablon oluşturma için kapsamlı bir mekanizmaya sahip olanı kullanmaktır . Bu, özellikle paketlerinizin, uygulamanızı güncellediğinizde tarayıcı önbelleğe alma sorunlarını önlemek için güzel bir paket hash ile sonlandırılmasını istiyorsanız yararlıdır.

Bir ad kalıbı tanımladığınızdan [id].bundle_[chunkhash].js, javascript paketinize artık main.bundle.jsbenzer şekilde adlandırılacağı için referans veremezsiniz main.bundle_73efb6da.js.

Html-webpack-eklentisine bir göz atın . Özellikle kullanım durumunuzla ilgili:

Muhtemelen sonunda böyle bir şeye sahip olmalısın (uyarı: test edilmedi)

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

Lütfen chunks dizisindeki giriş noktasının adına başvurduğunuza dikkat edin, bu nedenle örneğinizde bu olmalıdır exampleEntry. Muhtemelen şablonlarınızı doğrudan kök src klasörüne yerleştirmek yerine belirli bir klasöre taşımak da iyi bir fikirdir.

Bu yardımcı olur umarım.


4
İyi bir açıklama ama yine de projenizde oluşturduğunuz her farklı sayfa için 'yeni HTMLWebPlugin' çağırmanız beni rahatsız ediyor.
klewis

Herkes sayfaların her birine 'yeni HTMLWebPlugin' demekten hoşlanmaz. Alternatif lazım.
ChosenUser

4

HtmlWebpackPlugin'i kullanırken Birden Fazla HTML dosyası Webpackkullanmak için :

webpack.config.jsDoğrudan aşağıdaki kodu yerleştirerek değiştirin .

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

htmlPageNamesDiziye gerektiği kadar HTML sayfası ekleyebilirsiniz . Her HTML'nin ve karşılık gelen JS dosyasının aynı ada sahip olduğundan emin olun (Yukarıdaki kod bunu varsaymaktadır).


Bu iyi bir yaklaşımdı. ES6 sözdizimini kullanmasına rağmen. Buraya bakın .
robev

3

İki farklı yapıya ihtiyacınız yoksa, yani sadece aynı HTML ile farklı bir HTML sunmak istediğinizi varsayarak, Copy Webpack Eklentisini de kullanabilirsiniz main.bundle.js.

Eklenti gerçekten çok basit (yalnızca webpack v4'te test edildi):

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

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

Daha sonra example.htmlyapıyı şuradan yükleyebilirsiniz index.html. Örneğin:

<!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
Doğrudan html dosyasında komut dosyası referansı vermek yerine CopyWebpackPlugin'i kullanmanın ve bundle.js dosyasını webpack aracılığıyla html dosyasına eklemenin başka bir yolu var mı?
Sritam Jagadev

0

Webpack ^ 4.44.1 olduğunu varsayan başka bir çözüm var. Yani, HTML'yi JS / TS uygulamanıza içe aktarmak.

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

İlgili uygulama

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'yi ilgili çıktı klasörüne kopyalayacaktır.


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

Çok sayıda şablonunuz varsa bu kod yardımcı olacaktır :)

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.