【问题标题】:NODE_ENV in webpack react app is not being set corretlywebpack react 应用程序中的 NODE_ENV 未正确设置
【发布时间】:2018-04-13 14:55:23
【问题描述】:

我正在构建一个简单的 React 应用程序,并将其部署到 S3。我以 Facebook 的 create-react-app 为起点。我想在我的 index.html 中添加一个条件,这样我就只在生产中包含 Google Analytics。

为了测试它是否正常工作,我有这样的代码:(一旦我验证一切正常,我打算将下面的字符串更改为'production'

<%= '%NODE_ENV%' %>
<% if ('%NODE_ENV%' == 'development') { %>
  <!-- Global site tag (gtag.js) - Google Analytics -->
  <script async src="https://www.googletagmanager.com/gtag/js?id=XXX"></script>
<% } %>

当我使用 npm run start 在本地加载我的应用程序时。我看到它在页面上打印development,但 Google Analytics 脚本标签不在页面上。 怎么可能在我的 webpack JS 的第一行 %NODE_ENV% 等于 'development' 然后在下一行条件失败??

这是本地输出的 HTML:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <meta name="theme-color" content="#000000">
    <title>React App</title>
  </head>
  <body>
    <noscript>
      You need to enable JavaScript to run this app.
    </noscript>
    <div id="root"></div>
    <!--
      This HTML file is a template.
      If you open it directly in the browser, you will see an empty page.

      You can add webfonts, meta tags, or analytics to this file.
      The build step will place the bundled scripts into the <body> tag.

      To begin the development, run `npm start` or `yarn start`.
      To create a production bundle, use `npm run build` or `yarn build`.
    -->
    development

  <script type="text/javascript" src="/static/js/bundle.js"></script></body>
</html>

如您所见,它打印了'development',但随后出现了一个空行,如果条件通过,脚本标签将消失。

我是 webpack 的新手,我对这种行为感到非常困惑。任何帮助将不胜感激!

【问题讨论】:

  • 你能分享一下你的package.json,你用的是哪个版本的webpack
  • 这是我的 package.json 中的相关行:"html-webpack-plugin": "2.29.0", "extract-text-webpack-plugin": "3.0.2", "case-sensitive-paths-webpack-plugin": "2.1.1", "webpack": "3.8.1", "webpack-dev-server": "2.9.4", "webpack-manifest-plugin": "1.3.2", "sw-precache-webpack-plugin": "0.11.4",
  • 不确定如何在 SO cmets 中进行换行。很抱歉那里的混乱。
  • 我还应该注意,我没有更改 create-react-app 附带的任何 webpack 配置文件

标签: reactjs webpack webpack-dev-server create-react-app html-webpack-plugin


【解决方案1】:

经过大量调查,我想我已经弄清楚这里发生了什么。第一行是正确的,然后第二行是正确的原因与您的代码无关,而是与 create-react-app 实际插入这些环境变量的方式有关。

create-react-app 正在使用一个名为 InterpolateHtmlPlugin 的插件,它从 HtmlWebpackPlugin 调用一个钩子。基本上 InterpolateHtmlPlugin 所做的就是在 HTML 中查找 %env_var_name% 并将其替换为应用程序中环境对象中的相应值。

问题在于,当 HTML 进入 InterpolateHtmlPlugin 时,模板代码已经被处理(经过我的测试,我很确定这是真的)。由于它已经被处理,因此条件已评估为 false 并且不再显示在 HTML 中。对于第一行,它显示在 %NODE_ENV%,因此 Interpolate 将其拾取并替换它。

我认为最简单的做法是将 NODE_ENV 添加到 webpack 配置中的 HtmlWebpackPlugin 并以这种方式引用它。所以你的新 HtmlWebpackPlugin 配置看起来像这样:

new HtmlWebpackPlugin({
  inject: true,
  template: paths.appHtml,
  NODE_ENV: env.raw.NODE_ENV
})

您的 index.html 文件中的条件如下所示:

<% if (htmlWebpackPlugin.options.NODE_ENV == 'development') { %>
  <!-- Global site tag (gtag.js) - Google Analytics -->
  <script async src="https://www.googletagmanager.com/gtag/js?id=XXX"></script>
<% } %>

【讨论】:

  • 知道了。也许 InterpolateHtmlPlugin 运行得太晚了?即它挂在了生命周期中的错误阶段。无论如何,您的解决方案有效。老实说,我真的不需要 %VAR_NAME% 糖。我很高兴做htmlWebpackPlugin.options。似乎它让我用更少的魔法获得了更多的控制权。再次感谢!!
  • 是的,如果它想支持将变量用作 HtmlWebpackPlugin 使用的模板的真实部分,我认为它可能在错误的钩子期间运行。
【解决方案2】:
<% if (process.env.NODE_ENV == 'development') { %>
  <!-- Global site tag (gtag.js) - Google Analytics -->
  <script async src="https://www.googletagmanager.com/gtag/js?id=XXX"></script>
<% } %>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-01-01
    • 2016-05-30
    • 2021-12-08
    • 1970-01-01
    • 1970-01-01
    • 2019-07-27
    • 2018-02-10
    • 1970-01-01
    相关资源
    最近更新 更多