EJS + htmlWebpackPlugin + ejs-compiled-loader。无法使用循环制作导航列表,获取TypeErrors

时间:2018-07-30 12:35:13

标签: for-loop webpack ejs html-webpack-plugin

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

index.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无法使用传递的参数,那么哪些易于维护的替代方法呢? P.s.这是我在这里问的第一个问题,请不要判断得太严格。预先感谢。

已解决

nav.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
        }),
    }
    // ...
};

index.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>

那个shuold肯定有用。

2 个答案:

答案 0 :(得分:1)

以下是问题作者Alex Naidovichedited into their question(该修订版中“ SOLVED”下方的所有内容)并指示其已解决问题的代码。它的版权为2018 Alex Naidovich,并获得CC BY-SA 4.0许可。

nav.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

        }),
    }

    // ...

};

index.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>

那肯定可以。

答案 1 :(得分:0)

我只是遇到了类似的情况,对于我的项目,这是由于使用了webpack4。我最好选择compile-ejs-loader

我还没有尝试为模板传递对象,我所需要的只是ejs包含支持。