jantimon/html-webpack-plugin

How to bundle all of app's templates, styles and scripts into one single .js file, that can be exported as a library and attached to another HTML file and load?

ar-IGT opened this issue · 0 comments

ar-IGT commented

Currently I have such webpack.config.js file:

const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const path = require('path');
const TerserPlugin = require('terser-webpack-plugin');

const config = {
  context: path.resolve(__dirname, '.'),
  devServer: {
    client: {
      logging: 'verbose',
      overlay: true,
    },
    static: {
      directory: path.join(__dirname, './dist'),
    },
    compress: true,
    port: 9001,
  },
  entry: {
    commons: '../shared_libs/modules/commons.js',
    xmg_mm_wrapper_bottom_banner: [
        './src/css/xmg/marketing_base.css',
      './modules/xmg_mm_wrapper_bottom_banner.js'
    ],
    xmg_mm_wrapper_overhead_display: [
        './src/css/xmg/marketing_base.css',
      './modules/xmg_mm_wrapper_overhead_display.js'
    ],
    xmg_media_scheduler: [
        './src/css/xmg/media_scheduler_base.css',
      './modules/xmg_media_scheduler.js'
    ],
    xmg_window_manager: [
        './src/css/xmg/window_manager_base.css',
      './modules/xmg_window_manager.js'
    ],
    vendors: '../shared_libs/modules/vendors.js',
  },
  mode: 'production',
  module: {
    rules: [
      {
        exclude: /node_modules/,
        loader: 'babel-loader',
        test: /\.js$/
      },
      {
        exclude: /node_modules/,
        test: /\.css$/,
        use: [
          MiniCssExtractPlugin.loader,
          'css-loader',
        ]
      }
    ]
  },
  optimization: {
    minimize: true,
    minimizer: [
      new CssMinimizerPlugin({
        test: /\.css$/i
      }),
      new TerserPlugin({
        test: /\.js$/i
      }),
    ],
  },
  output: {
    filename: 'js/[name].[contenthash].js',
    path: path.resolve(__dirname, 'dist'),
    publicPath: '/'
  },
  performance: {
    maxEntrypointSize: 512000,
    maxAssetSize: 512000
  },
  plugins: [
    new HtmlWebpackPlugin({
      chunks: ['commons', 'xmg_mm_wrapper_bottom_banner', 'vendors'],
      chunksSortMode: function (a, b) {
        return a.startsWith('v') ? -1 : a.startsWith('c') ? 1 : 0;
      },
      filename: 'xmg_mm_wrapper_bottom_banner.html',
      scriptLoading: 'blocking',
      template: 'src/html/xmg_mm_wrapper_template.ejs',
      templateParameters: {
        initConsoleLog: 'MMWrapper start'
      }
    }),
    new HtmlWebpackPlugin({
      chunks: ['commons', 'xmg_mm_wrapper_overhead_display', 'vendors'],
      chunksSortMode: function (a, b) {
        return a.startsWith('v') ? -1 : a.startsWith('c') ? 1 : 0;
      },
      filename: 'xmg_mm_wrapper_overhead_display.html',
      scriptLoading: 'blocking',
      template: 'src/html/xmg_mm_wrapper_template.ejs',
      templateParameters: {
        initConsoleLog: 'MMWrapper start'
      }
    }),
    new HtmlWebpackPlugin({
      chunks: ['commons', 'xmg_media_scheduler', 'vendors'],
      chunksSortMode: function (a, b) {
        return a.startsWith('v') ? -1 : a.startsWith('c') ? 1 : 0;
      },
      filename: 'xmg_media_scheduler.html',
      scriptLoading: 'blocking',
      template: 'src/html/xmg_mm_wrapper_template.ejs',
      templateParameters: {
        initConsoleLog: 'xmg.MediaScheduler start'
      }
    }),
    new HtmlWebpackPlugin({
      chunks: ['commons', 'xmg_window_manager', 'vendors'],
      chunksSortMode: function (a, b) {
        return a.startsWith('v') ? -1 : a.startsWith('c') ? 1 : 0;
      },
      filename: 'xmg_window_manager.html',
      scriptLoading: 'blocking',
      template: 'src/html/xmg_mm_wrapper_template.ejs',
      templateParameters: {
        initConsoleLog: 'xmg.WindowManager start'
      }
    }),
    new MiniCssExtractPlugin({
      filename: 'css/[name].[contenthash].css',
    }),
  ]
};

module.exports = config;

And this config is used to build scripts, styles and templates (as HTML files), put separately in directories.
Then, scripts and styles are attached in HTML files built from .ejs template.

What I want to achieve, is this:

  1. build entry that is described by dependecies in array, so like xmg_mm_wrapper_bottom_banner
  2. paste into built entry a HTML code built from .ejs template and styles, that are matching this entry
  3. minimize and uglify what's possible
  4. make it an exportable library, so the .js file will load also styles and template
  5. repeat for every entry, besides vendors and commons
  6. add all of built, minified and uglyfied scripts into single script library-like file, in which every built script will be loaded
  7. make sure the vendors and then commons entries (in that order, also minified and uglified) will be put first, at the start of the single file library

The result should be single file library that after attaching on some 3rd party HTML file, will load own HTML, styles and logic.

Any ideas how to remake this config to get needed results?

Environment

Node.js v14.21.3, win32 10.0.19045

npm version: 6.14.18

webpack@5.88.1

html-webpack-plugin@5.5.3