【问题标题】:React app runs locally but fails with unexpected token '<' when pushed to heroku (prod)React 应用程序在本地运行,但在推送到 heroku(产品)时因意外令牌“<”而失败
【发布时间】:2020-09-12 16:50:12
【问题描述】:

我一直在重构我的 webpack 配置有两个原因。首先,要从中删除extract-text-webpack-plugin,因为它已被弃用,显然我应该使用MiniCssExtractPlugin 而不是css。其次,使用splitChunks 为我的代码与 node_modules 中的所有内容创建一个单独的 js 和 css 文件似乎是个好主意。似乎可以很好地解决一个问题,当我运行 heroku push 然后尝试加载我的应用程序时,浏览器在控制台中抛出 Uncaught SyntaxError: Unexpected token '&lt;' 错误并且我得到一个空白页面。

  • 在 dev-server 下运行良好。
  • 它在 heroku local 下运行良好。
  • 我浏览了 heroku 的故障排除页面,没有看到任何与版本控制、gitignore、node_modules 等有关的内容。
  • 我今天用谷歌搜索了这个错误并阅读了其他堆栈溢出文章,但无济于事。似乎基本问题与期望 js 的浏览器有关,但它正在获取 html。与没有正确转换有关吗?所以我在想我的 babel 配置和现在的多个文件可能出了点问题,但承认我不知道我是否走在正确的轨道上(例如 vendor.build.js 文件没有正确转换?)。
  • 所以我怀疑这个问题与以某种方式拆分我的输出文件有关..

在我看来唯一不同的是当我运行开发版本和生产版本时生成的文件,尽管我不确定这是否是问题的根源。显然我做错了什么,但我不知道是什么。

浏览器错误截图:

这是vendors.bundle.js 中的意外令牌错误所指的内容。这是我的应用程序的index.html 文件顺便说一句:

在我上面的重构练习之后,基于以下 webpack 配置,开发构建生成了 4 个文件:

产品构建会产生更多文件:

我的webpack.config.js 文件如下所示:

const path = require("path");
const webpack = require("webpack");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
// const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;

process.env.NODE_ENV = process.env.NODE_ENV || "development";

if (process.env.NODE_ENV === "test") {
  require("dotenv").config({ path: ".env.test" });
} else if (process.env.NODE_ENV === "development") {
  require("dotenv").config({ path: ".env.development" });
}

module.exports = (env) => {
  const isProduction = env === "production";

  return {
    entry: ["babel-polyfill", "./src/app.js"],
    output: {
      path: path.join(__dirname, "public", "dist"),
      filename: "bundle.js",
    },
    optimization: {
      splitChunks: {
        cacheGroups: {
          default: false,
          vendor: {
            test: /[\\/]node_modules[\\/]/,
            name: 'vendors',
            chunks: 'all'
          },
        },
      },
    },
    mode: isProduction ? 'production' : 'development',
    module: {
      rules: [
        {
          loader: "babel-loader",
          test: /\.js$/,
          exclude: /node_modules/,
        },
        {
          test: /\.less$/,
            use: [
              {
                loader: MiniCssExtractPlugin.loader,
                options: {
                  sourceMap: !isProduction,
                },
              },
              {
                loader: "css-loader",
                options: {
                  sourceMap: !isProduction,
                },
              },
              {
                loader: "less-loader",
                options: {
                  sourceMap: !isProduction,
                  modifyVars: {
                    "primary-color": "#1c88bf",
                    "link-color": "#1c88bf",
                    "border-radius-base": "2px",
                  },
                  javascriptEnabled: true,
                },
              }
            ],
        },
        {
          test: /\.s?css$/,
          use: [
            {
              loader: MiniCssExtractPlugin.loader,
              options: {
                sourceMap: !isProduction,
              },
            },
            {
              loader: "css-loader",
              options: {
                sourceMap: !isProduction,
              },
            },
            {
              loader: "sass-loader",
              options: {
                sourceMap: !isProduction,
              },
            },
          ],
        },
        {
          test: /\.(svg|eot|ttf|woff|woff2)$/,
          use: {
            loader: "file-loader",
            options: {
              name: "[name].[ext]",
              outputPath: "fonts/",
            },
          },
        },
      ],
    },
    plugins: [
      // new BundleAnalyzerPlugin(),
      new MiniCssExtractPlugin({ filename: '[name].css'}),
      new webpack.DefinePlugin({
        "process.env.FIREBASE_API_KEY": JSON.stringify(process.env.FIREBASE_API_KEY),
        "process.env.FIREBASE_AUTH_DOMAIN": JSON.stringify(process.env.FIREBASE_AUTH_DOMAIN),
        "process.env.FIREBASE_DATABASE_URL": JSON.stringify(process.env.FIREBASE_DATABASE_URL),
        "process.env.FIREBASE_PROJECT_ID": JSON.stringify(process.env.FIREBASE_PROJECT_ID),
        "process.env.FIREBASE_STORAGE_BUCKET": JSON.stringify(process.env.FIREBASE_STORAGE_BUCKET),
        "process.env.FIREBASE_MESSAGING_SENDER_ID": JSON.stringify(process.env.FIREBASE_MESSAGING_SENDER_ID),
      }),
    ],
    devtool: isProduction ? "source-map" : "inline-source-map",
    devServer: {
      contentBase: path.join(__dirname, "public"),
      historyApiFallback: true,
      publicPath: "/dist/",
    },
  };
};

我的.babelrc 文件值得一看..

{
  "presets": [
    "@babel/preset-env",
    "@babel/preset-react"
  ],
  "plugins": [
    "@babel/plugin-proposal-class-properties",
    "@babel/plugin-proposal-object-rest-spread",
    [
      "import",
      {
        "libraryName": "antd",
        "libraryDirectory": "es",
        "style": "true"
      }
    ]
  ]
}

【问题讨论】:

    标签: javascript reactjs heroku webpack babeljs


    【解决方案1】:

    您对 js 文件的调用似乎返回了您的 index.html,这就是浏览器抱怨 &lt; 的原因。检查是否有一些路由配置错误,如果没有命中会返回 index.html,然后查找它不匹配的原因。

    【讨论】:

      【解决方案2】:

      在我的情况下,问题是开发和生产版本之间的文件名不同(见上面的截图)。因此,我的 index.html 为生产构建引用了错误的文件名(参见上面的 index.html 脚本标签)。

      我最终通过两个更改修复了它。首先,我修复了我的 webpack 配置,以便为 dev 和 prod 构建输出相同的文件名。对于如何做到这一点,这对我来说并不是很明显(我不确定为什么 dev 使用 vendors.bundle.js 而 prod 使用 1.bundle.js),但它最终变得微不足道。在输出部分,我只需将文件名参数从"bundle.js" 更改为"[name].js"

      新文件名:

      webpack.config.js 更改:

          output: {
            path: path.join(__dirname, "public", "dist"),
            filename: "[name].js",
          },
      

      然后,我构建了 dev 和 prod 构建,以确认文件名现在相同。一旦我意识到它们是,我修改了我的 index.html 以使用之前的这两个文件名..

        <script src="/dist/vendors.js"></script>
        <script src="/dist/main.js"></script>
      

      【讨论】:

        猜你喜欢
        • 2013-01-29
        • 1970-01-01
        • 2014-10-24
        • 1970-01-01
        • 2020-08-03
        • 1970-01-01
        • 2019-11-03
        • 1970-01-01
        • 2020-07-17
        相关资源
        最近更新 更多