【问题标题】:Template in HTML, with Webpack, get error "variable" is not definedHTML中的模板,使用Webpack,得到错误“变量”未定义
【发布时间】:2018-08-16 22:32:49
【问题描述】:

我在 index.html 中创建了模板来生成带有 js 的 html 代码,代码如下。我的 Webpack 配置也在下面。当我使用 webpack-dev-server 运行它时,出现错误:未定义标题。不知何故,webpack 尝试自行解析“标题”,而不是将其委托给“lodash/template”。请帮我修复代码,我很绝望(。

import path from 'path';
import glob from 'glob';
import webpack from 'webpack';

import ExtractTextPlugin from 'extract-text-webpack-plugin';
import HtmlWebpackPlugin from 'html-webpack-plugin';

const inProduction = process.env.mode === 'production';

export default {
  entry: {
    app: [
      './src/scripts/main.js',
    ],
  },
  output: {
    path: path.join(__dirname, 'build'),
    filename: '[name].[chunkhash].js',
  },
  module: {
    rules: [
      {
        test: /\.s[ac]ss$/,
        use: ExtractTextPlugin.extract({
          use: ['css-loader', 'sass-loader'],
          fallback: 'style-loader',
        }),
      },
      {
        test: /\.js$/,
        use: 'babel-loader',
        exclude: '/node_modules',
      },
    ],
  },
  plugins: [
    new ExtractTextPlugin('[name].[chunkhash].css'),
    new webpack.LoaderOptionsPlugin({
      minimize: inProduction,
    }),
    new HtmlWebpackPlugin({
      template: path.join(__dirname, './src/index.html'),
    }),
  ],
};

import temp from 'lodash/template'
import data from './data';

const titlePicDiscHalf = temp(document.getElementById('titlePicDiscHalf').innerHTML);
document.write(titlePicDiscHalf({ title: 'Hello World!' }));
<!doctype html>
<html lang="en">
  <head>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
  </head>
  <body>
    <script type="text/template" id="titlePicDiscHalf">
      <div class="titlePicDiscHalf">
        <div class="picture"></div>
        <div class="title"><%=title%></div>
        <div class="discription"></div>
        <div class="buttons"></div>
      </div>
    </script>
  </body>
</html>

【问题讨论】:

  • 更改模板使用的&lt;%= 和%&gt; 分隔符。
  • @dfsq,如果我将其更改为 &lt;$=title$&gt; 等其他符号,则不会出现错误,但它会呈现 &lt;$=title$&gt;,而不是“Hello world”
  • html-webpack-plugin 使用相同的模板语法。也许错误来自试图解析标题的插件?
  • @lukas-reineke 是的,这正是问题所在。

标签: javascript html webpack lodash


【解决方案1】:

问题在于 html-webpack-plugin 使用相同的模板标签&lt;%= %&gt; 将包信息插入到模板中。

你有两个选择。

1。更改 lodash.template 分隔符

您可以将客户端 lodash/template 使用的分隔符更改为其他内容,因此 Webpack 会忽略它。例如:

_.templateSettings.interpolate = /<\$=([\s\S]+?)\$>/g;

看看这个演示。

_.templateSettings.interpolate = /<\$=([\s\S]+?)\$>/g;

const temp = _.template
const titlePicDiscHalf = temp(document.getElementById('titlePicDiscHalf').innerHTML);

document.write(titlePicDiscHalf({ title: 'Hello World!' }));
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.5/lodash.min.js"></script>

<script type="text/template" id="titlePicDiscHalf">
  <div class="titlePicDiscHalf">
    <div class="picture"></div>
    <div class="title">
      <$=title$>
    </div>
    <div class="discription"></div>
    <div class="buttons"></div>
  </div>
</script>

2。更改 html-webpack-plugin 分隔符

单独安装ejs-loader 并配置html-webpack-plugin 以使用它来加载您的模板。在那里,您可以将分隔符更改为您的分隔符。它可能看起来像这样:

plugins: [
  new HtmlWebpackPlugin({
    template: './index.html.ejs',
  })
],
module: {
  rules: [
    { test: /\.ejs$/, loader: 'ejs-loader', query: {
      interpolate: /<\$=([\s\S]+?)\$>/g,
      evaluate: /<\$([\s\S]+?)\$>/g,
    }},
  ]
},

现在,您可以使用两组不同的分隔符配置您的模板,一组用于客户端捆绑包 lodash 模板,另一组用于html-webpack-plugin:

<!doctype html>
<html lang="en">
  <head>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <title><$= htmlWebpackPlugin.options.title $></title>
  </head>
  <body>
    <script type="text/template" id="titlePicDiscHalf">
      <div class="titlePicDiscHalf">
        <div class="picture"></div>
        <div class="title"><%= title %></div>
        <div class="discription"></div>
        <div class="buttons"></div>
      </div>
    </script>
  </body>
</html>

注意,&lt;title&gt;&lt;$= htmlWebpackPlugin.options.title $&gt;&lt;/title&gt; 被 webpack 使用,&lt;div class="title"&gt;&lt;%= title %&gt;&lt;/div&gt; 被客户端 lodash 使用。

【讨论】:

  • 感谢您的回答,但是否可以更改 webpack 语法设置而不是更改 lodash 语法?
  • @dfsq 你好。谢谢您的回答。如果我使用格式 我应该如何为 ejs-loader 编写正则表达式?这个插值://g,对我不起作用
  • @runia 应该是 interpolate: &lt;%-([\s\S]+?)%&gt; 和 evaluate: /&lt;%([\s\S]+?)%&gt;/g,。
  • @runia 好的,你试过我在&lt;$= 的回答中发布的内容吗?
  • @dfsq 我在 .ejs 文件中使用 。我尝试插值:'',评估://g 不起作用为了我。在我尝试插值后:“”,评估: //g 。也不行。我在模板执行失败时收到错误错误:ReferenceError:未定义配置。我用你的 2 项。 (更改 html-webpack-plugin 分隔符)
【解决方案2】:

以防万一其他人落入同样的陷阱,即只想使用包含 &lt;script&gt; 的静态 html 文件,然后遇到类似 Referenceerror: variable is not defined 的错误。

确保你没有使用 JS 模板字符串!

例如而不是做类似的事情

function addLoginStatus(user) {
    document.querySelector('.login-status').textContent = `You logged in as user.firstName`;
}

使用这样的东西:

function addLoginStatus(user) {
    document.querySelector('.login-status').textContent = 'You logged in as ' + user.firstName;
}

我发现使用模板字符串,webpack-html-plugin 模板自然会尝试解释它们,这在我的情况下不是故意的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-11-15
    • 2011-05-17
    • 1970-01-01
    • 1970-01-01
    • 2014-11-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多