我有一个 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"),
},
},
然而,一切都没有改变。也尝试修改为
路径:假;
同样的结果。
有什么想法吗?
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"),
},
};
让我们修改 (webpack.config.js) 中的 publicPath,因为它看起来是一个空字符串。
output: {
path: path.resolve(__dirname, 'path/to/output'),
filename: 'fileName.[ext]'
}