NODE_ENV webpack React 应用程序未正确设置

NODE_ENV in webpack react app is not being set corretly

我正在构建一个部署到 S3 的简单 React 应用程序。我使用 facebook 的 create-react-app 作为起点。我想在我的 index.html 中添加一个条件,以便我只在生产中包含 Google 分析。

为了测试它是否正常工作,我有这样的代码:(我打算在验证一切正常后将下面的字符串更改为 '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 的新手,我对这种行为感到很困惑。任何帮助将不胜感激!

经过大量调查,我想我已经明白这是怎么回事了。第一行正确然后第二行不正确的原因与您的代码无关,而是与 create-react-app 实际插入这些环境变量的方式有关。

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

问题是当 HTML 到达 InterpolateHtmlPlugin 时,模板代码已经被处理(经过我的测试,我很确定这是真的)。因为它已经被处理过,所以 conditional 被评估为 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>
<% } %>
<% 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>
<% } %>