File does not render correctly / cannot get variable from options
mateusz-grek opened this issue ยท 3 comments
Current behaviour ๐ฃ
I currently have the following file structure: emodelle.html located in the de folder takes the element from de/components/02_footer_section/index.html and injects its contents into itself.
de/emodelle.html
de/components/02_footer_section/index.html
de/emodelle.html
DATA FROM FOOTER:
<%= require('html-loader!./components/02_footer_section/index.html').default %>
DATA STRAIGHT FROM EMODELLE:
<%= htmlWebpackPlugin.options.newVariable %>
</main>
de/components/02_footer_section/index.html
<%= htmlWebpackPlugin.options.newVariable %>
</div>
This dynamic variable newVariable
comes from webpack.config.js
const htmlPluginEntries = templateFiles.map((template) => new HTMLWebpackPlugin({
inject: true,
hash: false,
filename: template.output,
template: path.resolve(environment.paths.source, template.input),
favicon: path.resolve(environment.paths.source, 'images', 'favicon.ico'),
newVariable: 'New Variable test'
}));
Webpack.config.js
/**
* Webpack main configuration file
*/
const path = require('path');
const fs = require('fs');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const HTMLWebpackPlugin = require('html-webpack-plugin');
const ImageMinimizerPlugin = require('image-minimizer-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const SitemapPlugin = require('sitemap-webpack-plugin').default;
const Glob = require('glob');
let filesToIncludeArr = [];
let filesToIncludeArrSitemap = [];
const filesToInclude = Glob.sync('src/**/*.html').map(function(file) {
filesToIncludeArr.push(file.replace('src/', ''));
filesToIncludeArrSitemap.push(file.replace('src/', '').replace('.html', '').replace('index', ''));
// filesToIncludeArr[entryKey] = file;
})
console.log(filesToIncludeArr);
// Example of simple string paths
const paths = filesToIncludeArrSitemap;
const environment = require('./configuration/environment');
const templateFiles = filesToIncludeArr
.filter((file) => ['.html', '.ejs'].includes(path.extname(file).toLowerCase())).map((filename) => ({
input: filename,
output: filename.replace(/\.ejs$/, '.html'),
}));
const htmlPluginEntries = templateFiles.map((template) => new HTMLWebpackPlugin({
inject: true,
hash: false,
filename: template.output,
template: path.resolve(environment.paths.source, template.input),
favicon: path.resolve(environment.paths.source, 'images', 'favicon.ico'),
newVariable: 'New Variable test'
}));
module.exports = {
entry: {
app: path.resolve(environment.paths.source, 'js', 'app.js'),
},
output: {
filename: 'js/[name].js',
path: environment.paths.output,
},
module: {
rules: [
{
test: /\.((c|sa|sc)ss)$/i,
use: [MiniCssExtractPlugin.loader, 'css-loader', 'postcss-loader', 'sass-loader'],
},
{
test: /\.js$/,
exclude: /node_modules/,
use: ['babel-loader'],
},
{
test: /\.(png|gif|jpe?g|svg|webp)$/i,
type: 'asset',
parser: {
dataUrlCondition: {
maxSize: environment.limits.images,
},
},
generator: {
filename: 'images/design/[name].[hash:6][ext]',
},
},
{
test: /\.(eot|ttf|woff|woff2)$/,
type: 'asset',
parser: {
dataUrlCondition: {
maxSize: environment.limits.images,
},
},
generator: {
filename: 'images/design/[name].[hash:6][ext]',
},
},
],
},
optimization: {
minimizer: [
'...',
new ImageMinimizerPlugin({
minimizer: {
implementation: ImageMinimizerPlugin.imageminMinify,
options: {
// Lossless optimization with custom option
// Feel free to experiment with options for better result for you
plugins: [
['gifsicle', { interlaced: true }],
['jpegtran', { progressive: true }],
['optipng', { optimizationLevel: 5 }],
// Svgo configuration here https://github.com/svg/svgo#configuration
[
'svgo',
{
plugins: [
{
name: 'removeViewBox',
active: false,
},
],
},
],
],
},
},
}),
],
},
plugins: [
new MiniCssExtractPlugin({
filename: 'css/[name].css',
}),
new CleanWebpackPlugin({
verbose: true,
cleanOnceBeforeBuildPatterns: ['**/*', '!stats.json'],
}),
new CopyWebpackPlugin({
patterns: [
{
from: path.resolve(environment.paths.source, 'images', 'content'),
to: path.resolve(environment.paths.output, 'images', 'content'),
toType: 'dir',
globOptions: {
ignore: ['*.DS_Store', 'Thumbs.db'],
},
},
{ from: "src/.htaccess"},
{ from: "src/robots.txt"},
{
from: path.resolve(environment.paths.source, 'videos'),
to: path.resolve(environment.paths.output, 'videos'),
toType: 'dir',
globOptions: {
ignore: ['*.DS_Store', 'Thumbs.db'],
},
},
],
}),
new SitemapPlugin({
base: 'https://citroenist-mag.ch/',
paths,
options: {
filename: 'sitemap.xml'
}
})
].concat(htmlPluginEntries),
target: 'web',
};
Expected behaviour โ๏ธ
When using the npm run dev
command, the newVariable
variable appears correctly from emodelle.html, but not from footer, but when I go directly to the footer file in the browser, I see the rendered variable.
It seems that when compiling, webpack only renders emodelle and takes its variables, while from footer it does not render anything, it only shows pure html as a string in emodelle.html
GOAL TO ACHIEVE
I would like to be able to add dynamic variables to the file de/components/02_footer_section/index.html which will then be rendered when compiling to emodelle.html
Reproduction Example ๐พ
Environment ๐ฅ
Node.js v21.5.0
linux 6.5.0-15-generic
npm version: 10.2.4
npm ls webpack
@weareathlon/frontend-webpack-boilerplate@5.16.0 /home/mateusz/Developer/xxx/xxx
โโโฌ babel-loader@9.1.0
โ โโโ webpack@5.75.0 deduped
โโโฌ clean-webpack-plugin@4.0.0
โ โโโ webpack@5.75.0 deduped
โโโฌ copy-webpack-plugin@11.0.0
โ โโโ webpack@5.75.0 deduped
โโโฌ css-loader@6.7.3
โ โโโ webpack@5.75.0 deduped
โโโฌ css-minimizer-webpack-plugin@4.2.2
โ โโโ webpack@5.75.0 deduped
โโโฌ html-loader@4.2.0
โ โโโ webpack@5.75.0 deduped
โโโฌ html-webpack-plugin@5.5.0
โ โโโ webpack@5.75.0 deduped
โโโฌ image-minimizer-webpack-plugin@3.8.1
โ โโโ webpack@5.75.0 deduped
โโโฌ mini-css-extract-plugin@2.7.2
โ โโโ webpack@5.75.0 deduped
โโโฌ postcss-loader@7.0.2
โ โโโ webpack@5.75.0 deduped
โโโฌ sass-loader@13.2.0
โ โโโ webpack@5.75.0 deduped
โโโฌ terser-webpack-plugin@5.3.6
โ โโโ webpack@5.75.0 deduped
โโโฌ webpack-cli@5.0.1
โ โโโฌ @webpack-cli/configtest@2.0.1
โ โ โโโ webpack@5.75.0 deduped
โ โโโฌ @webpack-cli/info@2.0.1
โ โ โโโ webpack@5.75.0 deduped
โ โโโฌ @webpack-cli/serve@2.0.1
โ โ โโโ webpack@5.75.0 deduped
โ โโโ webpack@5.75.0 deduped
โโโฌ webpack-dev-server@4.11.1
โ โโโฌ webpack-dev-middleware@5.3.3
โ โ โโโ webpack@5.75.0 deduped
โ โโโ webpack@5.75.0 deduped
โโโ webpack@5.75.0
npm ls html-webpack-plugin
@weareathlon/frontend-webpack-boilerplate@5.16.0 /home/mateusz/Developer/xxx/xxx
โโโ html-webpack-plugin@5.5.0
Please create reproducible test repo using github, thank you
Please see reproducible test repo as requested https://github.com/mateusz-grek/html-webpack-plugin-issue
Because html-loader doesn't support variables, it is a future of html-webpack-plugin, you need to pass variables into <%= require('html-loader!./components/02_footer_section/index.html').default %>
There is an old issue - webpack-contrib/html-loader#291, I recommend to use template engine for such purposes, we are still not sure it is a right solution to allow using require
inside HTML files, that is why it is not finished and don't work in some cases