Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ver. 5.6.0: Reference to htmlWebpackPlugin.options.filename in template contains "[name]" instead of actual file name #1848

Open
CarlRaymond opened this issue Apr 23, 2024 · 7 comments

Comments

@CarlRaymond
Copy link

Current behaviour 💣

In version 5.6.0, a reference to htmlWebpackPlugin.options.filename within a template file contains the the token [name]. It has not been replaced with the actual filename. In my case, it is ../../Pages/Shared/Bundles/[name].cshtml

Expected behaviour ☀️

In version 5.5.0, the reference has had the [name] token replaced with the filename: ../../Pages/Shared/Bundles/style.cshtml

Reproduction Example 👾

With version 5.6.0 and the configuration below, webpack generates the files main.cshtml, style.cshtml and validation.cshtml, but they are empty. Reverting to version 5.5.0 produces correct contents.

webpack.config.js:

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const Autoprefixer = require('autoprefixer');
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
const webpack = require('webpack');

module.exports = {

devtool: 'source-map',

entry: {
    style: './css/main.scss',
    main: './js/main.ts',
    validation: {
        import: './js/validation.ts',
        dependOn: 'main'
    }
},

output: {
    path: path.resolve(__dirname, 'wwwroot', 'dist'),
    filename: 'bundles/[name].js',
    publicPath: '/dist/',
    clean: true,
},

watchOptions: {
    ignored: [ '/node_modules/' ]
},

externals: {
    jquery: 'jQuery',
},

resolve: {
    extensions: [".js", ".ts", ".css"],
},

resolveLoader: {
    modules: [
        path.resolve(__dirname, 'js'), // Project-local loaders in js folder
        'node_modules'
    ],
},

module: {
    rules: [
        {
            test: /\.ts$/,
            use: 'ts-loader',
        },
        {
            test: /\.css$/,
            use: [MiniCssExtractPlugin.loader, 'css-loader'],
        },
        {
            test: /\.(scss)$/,
            use: [
                {
                    loader: MiniCssExtractPlugin.loader, // Extract into separate .css file
                },
                {
                    loader: 'css-loader', // Translates CSS into CommonJS modules
                },
                {
                    loader: 'postcss-loader', // Run postcss actions
                    options: {
                        postcssOptions: {
                            // postcss plugins, can be exported to postcss.config.js
                            plugins: [Autoprefixer]
                            },
                        },
                },
                {
                    loader: 'sass-loader', // compiles Sass to CSS
                    options: {
                        sourceMap: true,
                        sassOptions: {
                            quietDeps: false,
                        }
                    }
                },
            ],
        },
        {
            test: /\.woff($|\?)|\.woff2($|\?)|\.ttf($|\?)|\.eot($|\?)/i,
            type: 'asset/resource',
            generator: {
                filename: 'fonts/[name][ext][query]',
            },
        },
    ],
},
optimization: {
    splitChunks: {
        chunks: 'async',
        minSize: 20000,
        minRemainingSize: 0,
        minChunks: 1,
        maxAsyncRequests: 30,
        maxInitialRequests: 30,
        enforceSizeThreshold: 50000,
        cacheGroups: {
            defaultVendors: {
                test: /[\\/]node_modules[\\/]/,
                priority: -10,
                reuseExistingChunk: true,
            },
            default: {
                minChunks: 2,
                priority: -20,
                reuseExistingChunk: true,
            },
        },
    },
    minimizer: [
        new CssMinimizerPlugin(),
    ],
},
plugins: [
    new CleanWebpackPlugin(),
    new webpack.ProvidePlugin({
        $: 'jquery',
        jQuery: 'jquery',
        'window.jQuery': 'jquery',
        bootstrap: 'bootstrap',
    }),
    new HtmlWebpackPlugin({
        inject: false,
        filename: '../../Pages/Shared/Bundles/[name].cshtml',
        template: './js/bundletemplate.ejs',
    }),
    new MiniCssExtractPlugin({
        filename: 'css/[name].css',
        //ignoreOrder: false,

    }),
],

stats: {
    logging: 'verbose'
}
};

bundletemplate.ejs

<% 
//get bundle file we're currently building. eg site.cshtml
var pathParts = _.split(htmlWebpackPlugin.options.filename, '/')
var file = pathParts[_.size(pathParts)-1]
var fileParts = _.split(file, '.')
var curFile = fileParts[0]

//only show chunks that match current bundle file we're building
var chunkFile = ''
for (var chunk in htmlWebpackPlugin.tags.headTags) {
	var tempChunk = _.replace(htmlWebpackPlugin.tags.headTags[chunk], '</script>', '')
	var pathPartsChunk = _.split(tempChunk, '/') // htmlWebpackPlugin.tags.headTags[chunk], '/')
	var fileChunk = pathPartsChunk[_.size(pathPartsChunk)-1]
	var filePartsChunk = _.split(fileChunk, '.')
	var curChunkFile = filePartsChunk[0]
	
	if (curChunkFile == curFile) {
		chunkFile = htmlWebpackPlugin.tags.headTags[chunk]			
	}
}
%><%=chunkFile%>

Environment 🖥

Node.js v18.16.0
win32 10.0.19045
Waiting for the debugger to disconnect...
9.5.1
[email protected] C:\sandbox\UOE.WebsiteTemplates\content\UOE.Bootstrap5.Razor
├─┬ [email protected]
│ └── [email protected] deduped
├─┬ [email protected]
│ └── [email protected] deduped
├─┬ [email protected]
│ └── [email protected] deduped
├─┬ [email protected]
│ └── [email protected] deduped
├─┬ [email protected]
│ └── [email protected] deduped
├─┬ [email protected]
│ └── [email protected] deduped
├─┬ [email protected]
│ └── [email protected] deduped
├─┬ [email protected]
│ └── [email protected] deduped
├─┬ [email protected]
│ └── [email protected] deduped
├─┬ [email protected]
│ ├─┬ @webpack-cli/[email protected]
│ │ └── [email protected] deduped
│ ├─┬ @webpack-cli/[email protected]
│ │ └── [email protected] deduped
│ ├─┬ @webpack-cli/[email protected]
│ │ └── [email protected] deduped
│ └── [email protected] deduped
└─┬ [email protected]
└─┬ [email protected]
└── [email protected] deduped

[email protected] C:\sandbox\UOE.WebsiteTemplates\content\UOE.Bootstrap5.Razor
└── [email protected]

@alexander-akait
Copy link
Collaborator

Can you put your example using github? thank you

@CarlRaymond
Copy link
Author

I just published a minimal example at https://github.com/CarlRaymond/html-webpack-plugin-issue1848 with instructions to make it fail and succeed. Thanks!

@xXACCEXx
Copy link

I am having the exact same issue.

My attempt at a workaround was to provide a function to filename to generate the string, but the config just contains a reference to the function, instead of the generated string.

This leads to something along the lines of not processing the output filename before generating the values being passed to the templateContent function.

@xXACCEXx
Copy link

A little bit of research, and this version was the last version that works.

https://www.npmjs.com/package/html-webpack-plugin/v/5.5.3

@alexander-akait
Copy link
Collaborator

alexander-akait commented Jul 24, 2024

Sorry, please never rely on htmlWebpackPlugin.options (it will be removed in the next major release, except title), they are lazy evaleted, otherwise we can't calculate contenthash, so you need to find other logic

@alexander-akait
Copy link
Collaborator

A little bit of research, and this version was the last version that works.

https://www.npmjs.com/package/html-webpack-plugin/v/5.5.3

it works because we don't make it lazy, so contenthash doesn't work properly and invalidation was broken

@xXACCEXx
Copy link

Yea, thats cool. Just annoying since the version change between this one and the next is only a patch, but broke some of my code that hasn't changed in like a year.

Feels like the 'lazy' part of that is at least a minor change, instead of patch.

No worries though, I'll go through and make some changes on my project to handle this without depending on the .options interface.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants