最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - html-webpack-plugin multiple entry points adding all scripts - Stack Overflow

programmeradmin7浏览0评论

I'm building a project on an ejected react cli. The reason I ejected it is because there will be multiple pages being generated and some stand alone scripts that I wanted to make and have them take advantage of the ES6 and debugging tools provided by the boilerplate.

My problem is that while using the technique to build out multiple pages with html-webpack-plugin builds out the generated HTML files with both scripts from each page.

So, lets have a look at the basic entry point

Here's my basic web pack config.

...
entry: {

      devServerClient : require.resolve('react-dev-utils/webpackHotDevClient'),
      // Finally, this is your app's code:
      ...pages,

    },
...

As you can see, I'm using the same hot module reloading stuff that came with the boiler plate, but then I deviate to spread in values from the pages variable which is being required from another page:

const glob = require("glob");
const path = require("path");

const input_path = path.resolve(__dirname, "../src/apps/*/index.js");
const apps_directories = glob.sync(input_path);

let pages = {};

// Loop through them and append them to the pages object for processing.
apps_directories.map(function (app_directory) {
    const split_name = app_directory.split("/");
    pages[split_name[split_name.length - 2]] = app_directory;
});

module.exports = pages;

Thats how I generate multiple entries dynamically. This portion of the code works fine, but I thought I'd post it just in case something needs to happen here that I'm missing.

Next We have the actual plugin section. I take a similar approach in modularizing the code, so here's that portion in the config (root level of the web pack object):

...
plugins: [
    // Generates an `index.html` file with the <script> injected.
    ...HtmlWebpackPlugins,
    ...
]
...

Again, I spread them in, the script that generates these looks like so:

const HtmlWebpackPlugin = require('html-webpack-plugin');
const pages = require("./multiplePaths");
const paths = require("./paths");

const NODE_ENV = process.env.NODE_ENV;

let HtmlWebpackPlugins = [];

Object.keys(pages).map(function (fileName) {
    if (NODE_ENV === "development") {
        HtmlWebpackPlugins.push( new HtmlWebpackPlugin({
            inject: true,
            template: paths.appHtml,
            filename: `${fileName}.html`,
        }));
        return;
    }

    HtmlWebpackPlugins.push(new HtmlWebpackPlugin({
        inject: true,
        template: paths.appHtml,
        filename:  `${fileName}.html`,
        minify: {
            removeComments: true,
            collapseWhitespace: true,
            removeRedundantAttributes: true,
            useShortDoctype: true,
            removeEmptyAttributes: true,
            removeStyleLinkTypeAttributes: true,
            keepClosingSlash: true,
            minifyJS: true,
            minifyCSS: true,
            minifyURLs: true,
        },
    }));
});

module.exports = HtmlWebpackPlugins;

This script here generates the multiple instances of the HtmlWebpackPlugin class per entry, and we also name the html file based on the folder the name of the folder the app resides in. This satisfies the technique in their issues section.

The problem then happens in the generated HTML page. Notice that the scripts for all the folders are injected in each app:

As you can see, each app's CSS and JS are added. This happens to both pages. I only want the relevant CSS and JS to each page.

Any idea what's going on here?

I'm building a project on an ejected react cli. The reason I ejected it is because there will be multiple pages being generated and some stand alone scripts that I wanted to make and have them take advantage of the ES6 and debugging tools provided by the boilerplate.

My problem is that while using the technique to build out multiple pages with html-webpack-plugin builds out the generated HTML files with both scripts from each page.

So, lets have a look at the basic entry point

Here's my basic web pack config.

...
entry: {

      devServerClient : require.resolve('react-dev-utils/webpackHotDevClient'),
      // Finally, this is your app's code:
      ...pages,

    },
...

As you can see, I'm using the same hot module reloading stuff that came with the boiler plate, but then I deviate to spread in values from the pages variable which is being required from another page:

const glob = require("glob");
const path = require("path");

const input_path = path.resolve(__dirname, "../src/apps/*/index.js");
const apps_directories = glob.sync(input_path);

let pages = {};

// Loop through them and append them to the pages object for processing.
apps_directories.map(function (app_directory) {
    const split_name = app_directory.split("/");
    pages[split_name[split_name.length - 2]] = app_directory;
});

module.exports = pages;

Thats how I generate multiple entries dynamically. This portion of the code works fine, but I thought I'd post it just in case something needs to happen here that I'm missing.

Next We have the actual plugin section. I take a similar approach in modularizing the code, so here's that portion in the config (root level of the web pack object):

...
plugins: [
    // Generates an `index.html` file with the <script> injected.
    ...HtmlWebpackPlugins,
    ...
]
...

Again, I spread them in, the script that generates these looks like so:

const HtmlWebpackPlugin = require('html-webpack-plugin');
const pages = require("./multiplePaths");
const paths = require("./paths");

const NODE_ENV = process.env.NODE_ENV;

let HtmlWebpackPlugins = [];

Object.keys(pages).map(function (fileName) {
    if (NODE_ENV === "development") {
        HtmlWebpackPlugins.push( new HtmlWebpackPlugin({
            inject: true,
            template: paths.appHtml,
            filename: `${fileName}.html`,
        }));
        return;
    }

    HtmlWebpackPlugins.push(new HtmlWebpackPlugin({
        inject: true,
        template: paths.appHtml,
        filename:  `${fileName}.html`,
        minify: {
            removeComments: true,
            collapseWhitespace: true,
            removeRedundantAttributes: true,
            useShortDoctype: true,
            removeEmptyAttributes: true,
            removeStyleLinkTypeAttributes: true,
            keepClosingSlash: true,
            minifyJS: true,
            minifyCSS: true,
            minifyURLs: true,
        },
    }));
});

module.exports = HtmlWebpackPlugins;

This script here generates the multiple instances of the HtmlWebpackPlugin class per entry, and we also name the html file based on the folder the name of the folder the app resides in. This satisfies the technique in their issues section.

The problem then happens in the generated HTML page. Notice that the scripts for all the folders are injected in each app:

As you can see, each app's CSS and JS are added. This happens to both pages. I only want the relevant CSS and JS to each page.

Any idea what's going on here?

Share Improve this question edited Oct 17, 2018 at 0:23 Philll_t asked Oct 17, 2018 at 0:13 Philll_tPhilll_t 4,4377 gold badges47 silver badges60 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 16

If you want to add only some of the chunks inside each page you need to specify which chunks exactly you want to have inside your html as scripts:

HtmlWebpackPlugins.push(new HtmlWebpackPlugin({
    inject: true,
    template: paths.appHtml,
    filename:  `${fileName}.html`,
    chunks: [filename], // add any chunks you need here (for example, chunk with libraries
    ....
});

I used something like this to create entries for HtmlWebpackPlugin based on webpack entries:

// Webpack entries
const entry = {
  "nameA": "./xy/nameA/main.js",
  "nameB": "./xy/nameB/main.js",
};

// Plugins
let plugins = [];

// HTML injection
Object.keys(entry).forEach((ent) => {
    const htmlPlugin = new HtmlWebpackPlugin({
      inject: true,
      title: "Your Title",
      template: "./html/index.html",
      filename: `formats/${ent}/index.html`,
      chunks: [ent],
    });
    plugins.push(htmlPlugin);
});

// Insert more plugins
plugins = plugins.concat([
    ... your plugins
]);

// Return Config
return {
  // define entry point
  entry,

  // define output file
  output: {
      ...
  },

  ...

  // define Plugins
  plugins,
  
  ...
  
  };
发布评论

评论列表(0)

  1. 暂无评论