首页 > 解决方案 > EJS + htmlWebpackPlugin + ejs-compiled-loader。无法使用循环制作导航列表,获取 TypeErrors

问题描述

我的目标是从传递给选项的数据创建导航htmlWebpackPlugin,我想使用for循环创建它。每次我尝试时,我都会遇到类似Cannot read property 'length' of undefined. 另外,我使用ejs-compiled-loader是因为我需要使用<%- include path/to/template %>. 而且我不使用express(如果没有其他方法,我会使用它)。

索引.ejs:

<!-- index.ejs -->
<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width">
    <title><%= htmlWebpackPlugin.options.title %></title>
</head>
<body>

<%- include app/templates/header %>

</body>
</html>

header.ejs:

<!-- header.ejs -->
<div class="header">

  <div class="header-inner">

    <div class="header-logo"><img src="../../assets/images/logo.png" alt="Logo"></div>

    <div class="nav">
      <ul>
        <% for (var i = 0; i < htmlWebpackPlugin.options.navItems.length; i++) { %>

          <li><a href="<%= htmlWebpackPlugin.options.navItems[i].href %>">
            <%= htmlWebpackPlugin.options.navItems[i].title %>
          </a></li>

        <% } %>
      </ul>
    </div>

  </div>

</div>

webpack.config.js:

module.exports = {
    // ...
    plugins: [
        new webpack.DefinePlugin({
            IS_DEV: IS_DEV
        }),

        new HtmlWebpackPlugin({
            template: '!!ejs-compiled-loader!./index.ejs',
            title: appHtmlTitle
        }),

        // HEADER
        new HtmlWebpackPlugin({
            template: path.join(__dirname, 'app/templates/header.ejs'),
        //  template: '!!ejs-compiled-loader!./app/templates/header.ejs' tried as well
            navItems: [
              {
                href: './',
                title: 'startseite'
              },
              {
                href: './offers.html',
                title: 'angebote'
              },
              {
                href: './about.html',
                title: '&uuml;ber uns'
              },
              {
                href: './contact.html',
                title: 'kontakt'
              }
            ],
            test: 'Test'
        })
    ],
    module: {
        rules: [
            // BABEL
            {
                test: /\.js$/,
                loader: 'babel-loader',
                exclude: /(node_modules)/,
                options: {
                    compact: true
                }
            },

            // STYLES
            {
                test: /\.css$/,
                use: [
                    'style-loader',
                    {
                        loader: 'css-loader',
                        options: {
                            sourceMap: IS_DEV
                        }
                    },
                ]
            },

            // CSS / SASS
            {
                test: /\.scss/,
                use: [
                    'style-loader',
                    {
                        loader: 'css-loader',
                        options: {
                            sourceMap: IS_DEV
                        }
                    },
                    {
                        loader: 'sass-loader',
                        options: {
                            sourceMap: IS_DEV,
                            includePaths: [dirAssets]
                        }
                    }
                ]
            },

            // IMAGES
            {
                test: /\.(jpe?g|png|gif)$/,
                loader: 'file-loader',
                options: {
                    name: '[path][name].[ext]'
                }
            }
        ]
    }
};

我究竟做错了什么?如果ejs-compiled-loader无法访问传递的参数,那么易于维护的替代方案是什么?Ps 这是我在这里问的第一个问题,请不要判断太严格。提前致谢。

标签: for-loopwebpackejshtml-webpack-plugin

解决方案


以下是问题作者Alex Naidovich编辑到他们的问题中的代码(该修订版中“已解决”以下的所有内容)并表明它解决了问题。它是 2018 年 Alex Naidovich 的版权所有,并在 CC BY-SA 4.0 许可下。

导航.js:

module.exports = [
    {
        href: './',
        title: 'Home'
    }, {
        href: './about.html',
        title: 'About Us'
    }, {
        href: './contact.html',
        title: 'Contact Us'
    }
]

webpack.config.js:

const NAV = require('path/to/nav.js'); // without extension

module.exports = {

    // ...

    plugins: {

        // ...

        new HtmlWebpackPlugin({
            template: '!!ejs-compiled-loader!./index.ejs',
            filename: 'index.html',
            title: appHtmlTitle,

            NAV: NAV    // <- added NAV into plugin

        }),
    }

    // ...

};

索引.ejs:

<!doctype html>
<!-- html and head tags stuff -->
<body>

<% var NAV = htmlWebpackPlugin.options.NAV %> <!-- added this -->
<%- include app/templates/header %>

</body>
</html>

header.ejs:

<div class="header">
  <div class="header-inner">
    <div class="nav">
      <ul>

        <!-- header.ejs successfully gets variable NAV from index.ejs -->
        <% NAV.forEach(function(navItem) { %>

        <li>
          <a href="<%= navItem.href %>"> <%= navItem.title %> </a>
        </li>
        <% }) %>
      </ul>
    </div>
  </div>
</div>

那肯定行得通。


推荐阅读