11

我想使用 HTMLWebpackPlugin 来获取我的index.ejs模板文件,插入我的捆绑资产,并输出一个最终index.ejs文件。

这个例子有一个 EJS 变量<%= API_URL %>,但是 webpack 正在解释它。

如何阻止 webpack 替换变量?

开始“模板”:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>Monitor</title>
    <script>
      window.config = {
        API_URL: "<%= API_URL %>"
      }
    </script>
  </head>
  <body>
    <div class="container"></div>
  </body>
</html>

当你尝试运行 webpack 时:

ERROR in Template execution failed: ReferenceError: API_URL is not defined

期望的结果 index.ejs:(具有捆绑资产和 EJS var)

监控 window.config = { API_URL: "<%= API_URL %>" }

webpack.config.js

var webpack = require('webpack');
var path = require('path');
var HtmlWebpackPlugin = require('html-webpack-plugin');
var ExtractTextPlugin = require('extract-text-webpack-plugin');

module.exports = {
  entry: {
    bundle: './src/index.js'
  },
  output: {
    path: path.join(__dirname, 'dist'),
    filename: '[name].[chunkhash].js'
  },
  module: {
    rules: [
    {
      test: /\.js$/,
      use: 'babel-loader',
      exclude: /node_modules/
    },
    {
      // CSS is imported in app.js.
      test: /\.scss$/,
      use: ExtractTextPlugin.extract({
        fallbackLoader: 'style-loader',
        loader: ["css-loader", "sass-loader"]
      })
    }]
  },
  plugins: [
    new webpack.DefinePlugin({
      'process.env': {
        'NODE_ENV': JSON.stringify(process.env.NODE_ENV),
        'API_URL': JSON.stringify(process.env.API_URL)
      }
    }),
    new HtmlWebpackPlugin({
      template: 'src/index.ejs',
      inject: true
    }),
    new ExtractTextPlugin("styles.css")
  ],
};
4

5 回答 5

4

这是一个非常糟糕的hacky解决方案,我希望其他人对如何做到这一点有一个真正的答案/理解。

在您的模板文件 (index.ejs) 中,执行以下操作:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>Monitor</title>
    <script>
      window.config = {
        API_URL: "<%= htmlWebpackPlugin.options.API_URL_TEMPLATE_VAR %>"
      }
    </script>
  </head>
  <body>
    <div class="container"></div>
  </body>
</html>

在您的 webpack 配置中,执行此操作(相关部分是我定义变量的新 HtmlWebpackPlugin。:

plugins: [
    // Define environment variables that are accessible inside of app javascript.
    new webpack.DefinePlugin({
      'process.env': {
        'NODE_ENV': JSON.stringify(process.env.NODE_ENV)
      }
    }),
    // Adds bundled file links to the index.html
    new HtmlWebpackPlugin({
      // The input file name
      template: 'src/index.prod.ejs',
      // Injects scripts into the <body>
      inject: true,
      // This is so hacky. I inject a string so the built .ejs file has this template var. Lets us set api_url when server is started instead of at bundle time.
      API_URL_TEMPLATE_VAR: '<%= process.env.API_URL %>',
      // The output file name
      filename: 'index.ejs'
    }),
    new ExtractTextPlugin("styles.css")
  ],

因为我定义API_URL_TEMPLATE_VAR了,当 html-webpack-plugin 评估它时,它会打印<%= process.env.API_URL %>到最终的模板中。

哈克,但有效。不接受我自己的答案/等待更好的答案。

于 2017-05-07T23:03:23.273 回答
0

据我了解 EJS,您的问题将通过使用EJS 文档<%%=中的说明来解决,因此将您的代码替换为: ,API_URL: "<%%= API_URL %>"

于 2021-12-10T09:06:11.370 回答
0

HTMLWebpackPlugin 为此使用了 lodash.template ,虽然不是很容易将其默认分隔符更改为类似<?这样的东西,但您可以<%在前端使用分隔符。但是,如果您在前端使用 ejs 包,那么更改那里的分隔符并为 webpack 保留正常的分隔符会容易得多。

ejs:

<div>
  <%=SOME_WEBPACK_VAR%>
  <br />
  <?=SOME_EJS_VAR%>
</div>

javascript:

ejs.render(yourHtml, {SOME_EJS_VAR: 'foo'}, {delimiter: '?'});
于 2018-07-02T15:14:48.773 回答
0

我遇到了同样的问题,并在变量的定义中添加引号(“)解决了它:

在你的情况下:

new webpack.DefinePlugin({
  'process.env': {
    'NODE_ENV': JSON.stringify(process.env.NODE_ENV),
    'API_URL': '"' + JSON.stringify(process.env.API_URL) + '"'
  }
})
...
于 2017-11-04T15:31:16.207 回答
-1

如果您希望 Webpack 从构建中忽略您的文件,您可以在文件路径前面添加raw-loader ,如下所示:

new HtmlWebpackPlugin({
    inject: true,
    filename: "index.ejs",
    template: "!!raw-loader!" + 'src/index.ejs',
}),

如果你想直接从 Webpack 将变量注入到你的模板中,你可以使用一个名为 的依赖项react-dev-utils,它有一个非常方便的插件:

new InterpolateHtmlPlugin(HtmlWebpackPlugin, {
   PUBLIC_URL: publicUrl,
  // You can pass any key-value pairs, this was just an example.
  // WHATEVER: 42 will replace %WHATEVER% with 42 in index.html.
}),

我自己没有尝试过使用 ejs 模板,但我看不出它不应该工作的理由。

于 2021-03-19T15:53:21.847 回答