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

File does not render correctly / cannot get variable from options #1839

Open
mateusz-grek opened this issue Feb 1, 2024 · 3 comments
Open

Comments

@mateusz-grek
Copy link

mateusz-grek commented Feb 1, 2024

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

@mateusz-grek mateusz-grek changed the title How to render two files at once by injecting one into the other? Does not render a file that is used in another module. Feb 1, 2024
@mateusz-grek mateusz-grek changed the title Does not render a file that is used in another module. File does not render correctly / cannot get variable from options Feb 1, 2024
@alexander-akait
Copy link
Collaborator

Please create reproducible test repo using github, thank you

@mateusz-grek
Copy link
Author

Please see reproducible test repo as requested https://github.com/mateusz-grek/html-webpack-plugin-issue

@alexander-akait
Copy link
Collaborator

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

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

2 participants