【问题标题】:Error when trying to run dev server | React, SSR尝试运行开发服务器时出错 |反应,SSR
【发布时间】:2021-08-14 08:31:45
【问题描述】:

我在尝试运行服务器时遇到此错误:

E:...\node_modules\ts-loader\dist\watch-run.js:29 for (const [filePath, date] of times) { ^

TypeError: times 不可迭代 在 E:...\node_modules\ts-loader\dist\watch-run.js:29:44 在 Hook.eval [as callAsync] (eval at create (E:...\node_modules\tapable\lib\HookCodeFactory .js:33:10), :7:1) 在 Hook.CALL_ASYNC_DELEGATE [as _callAsync] (E:...\node_modules\tapable\lib\Hook.js:18:14) 运行时(E:...\node_modules\webpack\lib\Watching.js:138:33) 在 E:...\node_modules\webpack\lib\Watching.js:120:6 在 Compiler.readRecords (E:...\node_modules\webpack\lib\Compiler.js:908:11) 运行时(E:...\node_modules\webpack\lib\Watching.js:116:26) 在 E:...\node_modules\webpack\lib\Watching.js:112:6 在 E:...\node_modules\webpack\lib\HookWebpackError.js:69:3 在 E:...Hook.eval [as callAsync] (eval at create (\node_modules\tapable\lib\HookCodeFactory .js:33:10), :6:1)

-- 包.json--

 {
  "name": "",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "build": "webpack",
    "dev": "webpack serve"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "@types/react": "^17.0.7",
    "@types/react-dom": "^17.0.5",
    "ts-loader": "^9.2.2",
    "typescript": "^4.2.4",
    "webpack": "^5.37.1",
    "webpack-cli": "^4.7.0",
    "webpack-dev-server": "^3.11.2",
    "webpack-node-externals": "^3.0.0"
  },
  "dependencies": {
    "express": "^4.17.1",
    "nodemon": "^2.0.7",
    "react": "^17.0.2",
    "react-dom": "^17.0.2"
  }
}

-- dev.js--

const webpack = require('webpack');
const webpackConfig = require('../webpack.config');
const nodemon = require('nodemon');
const path = require('path');

const compiler = webpack(webpackConfig);

compiler.run((err) => {
  if(err) {
    console.log('Compilation failed: ', err)
  }

  compiler.watch({}, (err) => {
    if(err) {
      console.log('Compilation failed: ', err);
    }
    console.log('Compilation was successfully');
  });

  nodemon({
    script: path.resolve(__dirname, '../dist/server/server.js'),
    watch: [
      path.resolve(__dirname, '../dist/server'),
      path.resolve(__dirname, '../dist/client')
    ]
  })

});

-- webpack.server.config.js--

const path = require('path');

const nodeExternals = require('webpack-node-externals');

const NODE_ENV = process.env.NODE_ENV;

module.exports = {
  
  target: 'node',
  mode: NODE_ENV ? NODE_ENV : 'production',
  entry: path.resolve(__dirname, '../src/server/server.js'),
  output: {
    path: path.resolve(__dirname, '../dist/server'),
    filename: 'server.js'
  },
  resolve: {
    extensions: ['.ts', '.tsx', '.js']
  },
  externals: [nodeExternals()],
  module: {
    rules: [{
      test: /\.[jt]sx?$/,
      loader: 'ts-loader',
      exclude: /node_modules/
    }]
  },
  optimization: {
    minimize: false
  }
};

-- webpack.client.config.js--

const path = require('path');

const NODE_ENV = process.env.NODE_ENV;
    
module.exports = {

  mode: NODE_ENV ? NODE_ENV : 'production',

  entry: path.resolve(__dirname, '../src/client/index.tsx'),

  output: {
    path:  path.resolve(__dirname, '../dist/client'),
    filename: 'client.js'
  },

  resolve: {
    extensions: ['.ts', '.tsx', '.js']
  },

  module: {
    rules: [{
      test: /\.[jt]sx?$/,
      loader: 'ts-loader',
      exclude: /node_modules/
    }]
  }

}; // module.exports

-- webpack.config.js--

const clientConfig = require('./configs/webpack.client.config');
const serverConfig = require('./configs/webpack.server.config');

module.exports = [
  clientConfig,
  serverConfig
];

-- server.js--

import express from 'express';
import ReactDOM from 'react-dom/server';
import { Header } from "../shared/Header";

const app = express();

app.get('/', (req, res) => {
  res.send(
    ReactDOM.renderToString(Header())
  );
});

app.listen(4000, () => {
  console.log('Server started on port http://localhost:4000');
});

-- 文件夹结构--

【问题讨论】:

  • 为什么要构建服务器端反应渲染器?只需使用 NextJS 或 Gatsby
  • 另外我不认为你可以在 webpack 中有一个 react 组件作为你的入口

标签: node.js reactjs npm webpack server-side-rendering


【解决方案1】:

这个麻烦来自ts-loader。你可以看到拉取请求here

你应该使用 babel,而不是使用 ts-loader。 您需要在 webpack 配置中更改处理程序 .ts 和 .js。

{
            test: /\.[tj]sx?$/,
            use: {
                loader: 'babel-loader',
                options: {
                    presets: ['@babel/preset-env', '@babel/preset-react']
                }
            }
        }

同时添加 .babelrc :

{"presets": ["@babel/react", "@babel/typescript", ["@babel/env", { "modules": false }]]}

【讨论】:

    【解决方案2】:

    TypeError: times is not iterable

    除了我对你为什么使用服务器端反应渲染感到困惑(除非你正在尝试实验性的服务器端反应组件)之外,你要么需要根据上述错误修改你的代码,要么使times 可迭代。

    ES2015.Iterable 将其定义为

    interface Array<T> {
        /** Iterator */
        [Symbol.iterator](): IterableIterator<T>;
    
        /**
         * Returns an iterable of key, value pairs for every entry in the array
         */
        entries(): IterableIterator<[number, T]>;
    
        /**
         * Returns an iterable of keys in the array
         */
        keys(): IterableIterator<number>;
    
        /**
         * Returns an iterable of values in the array
         */
        values(): IterableIterator<T>;
    }
    

    这可能对您最有用:

    const times = 'StackOverflow'
    const iterable = [...Array(...times).values()]
    console.log(iterable);
    

    这样输出每个子字符如下:

    [LOG]: ["S", "t", "a", "c", "k", "O", "v", "e", "r", "f", "l", "o", "w"] 
    

    如果您不传播...times 而是使用times,它会输出const times 定义的字符串。或者,您可以使用数字代替字符串,例如 100。然后,它将返回

    [LOG]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99] 
    

    如果你想倒计时,那就写

    const times = 101
    const iterable = [...Array(times).keys()].reverse();
    
    

    上面输出从 100 开始的倒计时:

    [LOG]: [100, 99, 98, 97, 96, 95, 94, 93, 92, 91, 90, 89, 88, 87, 86, 85, 84, 83, 82, 81, 80, 79, 78, 77, 76, 75, 74, 73, 72, 71, 70, 69, 68, 67, 66, 65, 64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
    

    无论如何,您可以将 times 设为 Iterable,但值得注意的是,您缺少 ts-node 作为依赖项,如果您使用的是快速服务器,则应该使用它。

    【讨论】:

      猜你喜欢
      • 2020-03-13
      • 1970-01-01
      • 2019-05-21
      • 2016-06-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多