JSDOM 触发 webpack polyfill 问题

问题描述 投票:0回答:1

我有一个 MERN 项目。作为我尝试将前端部署到服务器的一部分,我试图使其在节点环境中工作。

第一期:

当我尝试在终端中运行以下命令时:

node ./build/static/js/index.js

我收到以下错误:

Error: Automatic publicPath is not supported in this browser
    at file://Users/123/JAN30/123reporter/front/dashboard/build/static/js/index.js:2:249085
    at file://Users/123/JAN30/123reporter/front/dashboard/build/static/js/index.js:2:249226
    at /Users/123/JAN30/123reporter/front/dashboard/build/static/js/index.js:152:80876
    at ModuleJob.run (node:internal/modules/esm/module_job:193:25)
    at async Promise.all (index 0)
    at async ESMLoader.import (node:internal/modules/esm/loader:530:24)
    at async loadESM (node:internal/process/esm_loader:91:5)
    at async handleMainPromise (node:internal/modules/run_main:65:12)

Node.js v18.12.1

这很有道理,因为我正在尝试运行 .js 代码,该代码预计在浏览器环境中运行,并且我试图强制它在节点环境中运行。

因此,为了解决这个问题,我尝试通过以下方式使用 jsdom

import React from 'react';
import ReactDOM from 'react-dom/client';
import './styles/index.css';
import App from './components/App';
import reportWebVitals from './reportWebVitals';
import { JSDOM } from "jsdom";
const dom = new JSDOM('<!doctype html><html><body><div id="root"></div></body></html>');
(global as any).window = dom.window;
global.document = dom.window.document;
const root: ReactDOM.Root = ReactDOM.createRoot(
  window.document.getElementById('root') as HTMLElement
);

root.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);

这让我......

第二期:

尝试使用上面写的 JSDOM 触发了以下新问题

Module not found: Error: Can't resolve 'fs' in '/Users/123/JAN30/123reporter/front/dashboard/node_modules/jsdom/lib'

好吧。这是有道理的,因为我在 Nodejs 环境中模拟 DOM 环境,但它没有找到 Nodejs 期望拥有的模块。

为了解决这个问题,我在 webpack.config 文件的 module.export 中添加了以下字段:

  node: {
    fs: "empty",
  },

现在我尝试重建,这让我..惊喜..

第三期:
Module not found: Error: Can't resolve 'path' in '/Users/123/JAN30/123reporter/front/dashboard/node_modules/jsdom/lib'
BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.

If you want to include a polyfill, you need to:
        - add a fallback 'resolve.fallback: { "path": require.resolve("path-browserify") }'
        - install 'path-browserify'
If you don't want to include a polyfill, you can use an empty module like this:
        resolve.fallback: { "path": false }

我尝试通过在 webpack.config 中添加以下内容来解决这个问题:

  resolve: {
    extensions: [".tsx", ".ts", ".js"],
    fallback: {
      path: require.resolve("path-browserify"),
    },
  },

然而,一切都没有改变。也尝试修改为

路径:假;

同样的结果。

有什么想法吗?

编辑:

添加 webpack 配置
const path = require("path");
const webpack = require("webpack");
const dotenv = require("dotenv");
dotenv.config();

module.exports = {
  entry: {
    index: "./src/index.tsx",
  },
  mode: "production",
  node: {
    fs: "empty",
  },
  module: {
    rules: [
      {
        test: /\.tsx?$/,
        use: [
          {
            loader: "ts-loader",
            options: {
              compilerOptions: { noEmit: false },
            },
          },
        ],
        exclude: /node_modules/,
      },
      {
        test: /\.css$/,
        use: [
          {
            loader: "css-loader",
          },
        ],
        exclude: /node_modules/,
      },
    ],
  },
  resolve: {
    extensions: [".tsx", ".ts", ".js"],
    fallback: {
      path: require.resolve("path-browserify"),
    },
  },
  plugins: [
    new webpack.DefinePlugin({
      "process.env": JSON.stringify(dotenv.config().parsed),
    }),
  ],
  output: {
    filename: "[name].js",
    path: path.resolve(__dirname, "build/static/js"),
  },
};
javascript node.js webpack deployment
1个回答
-1
投票

让我们修改 (webpack.config.js) 中的 publicPath,因为它看起来是一个空字符串。

output: {
           path: path.resolve(__dirname, 'path/to/output'),
           filename: 'fileName.[ext]'
       }
© www.soinside.com 2019 - 2024. All rights reserved.