Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get both EJS compilation and html-loader in html-webpack-plugin?

  1. I want my html-webpack-plugin to generate my html based on my .ejs template which also have some <img> tags.

  2. html-loader can change my <img> tags's image address to the one Webpack made, so I need it. I specifying this in rules

                test: /\.ejs$/, 
                use: ['html-loader'] 
    

But doing that disables the fallback "ejs-loader" of html-webpack-plugin as mentioned in https://github.com/jantimon/html-webpack-plugin/blob/master/docs/template-option.md (mentioned without answer) and so my <img> tags got replaced correctly but EJS not getting compiled.

If I remove this rule the EJS got compiled but the resulting html in my dist folder the <img> tags are still referring to old names.

I have also tried use: ['html-loader','ejs-compiled-loader'] which give me a strange module.exports = gibberish in my final HTML file (like it is to be invoked one last time, but didn't. Since Webpack says the final step expects a Javascrip or something..) while ONLY use: ['ejs-compiled-loader'] works fine (My EJS got compiled) and ONLY use: ['html-loader'] is also fine (my img tags got scanned)

How to get both? Thanks.

like image 246
5argon Avatar asked Nov 04 '17 15:11

5argon


People also ask

Can webpack bundle HTML?

The HtmlWebpackPlugin simplifies creation of HTML files to serve your webpack bundles. This is especially useful for webpack bundles that include a hash in the filename which changes every compilation.

What is HtmlWebpackPlugin template?

template: './src/index. html' – this option specifies which file to use as template for the index. html being created. title: 'My Awesome application' – this is a custom property we added to the config object, the value of this property would be used to embed in the placeholder element <%= htmlWebpackPlugin. options.

What is the use of HTML loader?

The html-loader defination says that it exports html as String (What does it mean). it also says that every loadable attributes (for example <img src="image. png" is imported as require('./image. png') ,and you may need to specify loader for images in your configuration ( file-loader or url-loader ), What does it mean.


1 Answers

You can't.

The simplest way, that I found, is to stick to EJS-templates all the way (even if it hurts ;))

So, name your template something that ends with .ejs.

index.ejs

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>WebPack Labs 001</title>
</head>
<body>
<h1><%= htmlWebpackPlugin.options.title %></h1>
<img src="<%= require('./img/kolfiber.jpg') %>" alt="">
</body>
</html>

Note the:

<img src="<%= require('./img/kolfiber.jpg') %>" alt="">

This is what makes the image(s) work.

This is what my plugins looks like in webpack.config.js:

plugins: [
            new HtmlWebpackPlugin({
                template: 'src/index.ejs',
                title: 'HTML Webpack Plugin',
            })
        ],

And here's the output:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>WebPack Labs 001</title>
<link href="/main.a543702ae62bbf007a2ec7ee6fb3571c.css" rel="stylesheet"></head>
<body>
<h1>HTML Webpack Plugin</h1>
<img src="/static/media/images/kolfiber.a3a95779.jpg" alt="">

<script type="text/javascript" src="/main.a713c115b35765d7d4ed.js"></script></body>
</html>

My complete, current config (not just for this example):

const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const I18nPlugin = require('i18n-webpack-plugin');
const path = require('path');

const languages = {
    en: null,
    de: require('./src/app/lang/de.json'),
};

module.exports = env => {
    console.log(env);

    const config = {
        entry: './src/app/js/index.js',
        output: {
            path: path.resolve(__dirname, './dist'),
            filename: '[name].[hash].js',
            publicPath: '/',
        },
        module: {
            rules: [
                {
                    test: /\.(gif|jpe?g|png|webp)$/,
                    loader: 'file-loader',
                    query: {
                        limit: 8192,
                        name: 'static/media/images/[name].[hash:8].[ext]',
                    },
                },
                {
                    test: /\.css$/,
                    use: ExtractTextPlugin.extract({
                        fallback: 'style-loader',
                        use: 'css-loader',
                    }),
                },
                {
                    test: /\.scss$/,
                    use: ExtractTextPlugin.extract({
                        fallback: 'style-loader',
                        use: ['css-loader', 'sass-loader'],
                    }),
                },
                {
                    test: /\.txt$/,
                    use: [
                        {
                            loader: 'file-loader',
                            options: {
                                name: '[name].[ext]',
                            },
                        },
                    ],
                },
            ],
        },
        plugins: [
            new webpack.DefinePlugin({
                PRODUCTION: JSON.stringify(true),
                LANGUAGE: languages,
            }),
            new HtmlWebpackPlugin({
                template: 'src/index.ejs',
                title: 'HTML Webpack Plugin',
            }),
            new ExtractTextPlugin({
                filename: '[name].[contenthash].css',
                disable: process.env.NODE_ENV === 'development',
            }),
            new I18nPlugin(languages.de, {
                failOnMissing: true,
                hideMessage: false,
            }),
        ],
    };

    return config;
};
like image 107
jBoive Avatar answered Oct 05 '22 03:10

jBoive