'Error when trying to run dev server | React, SSR
I got this error when I'm trying to run server:
E:...\node_modules\ts-loader\dist\watch-run.js:29 for (const [filePath, date] of times) { ^
TypeError: times is not iterable at E:...\node_modules\ts-loader\dist\watch-run.js:29:44 at Hook.eval [as callAsync] (eval at create (E:...\node_modules\tapable\lib\HookCodeFactory .js:33:10), :7:1) at Hook.CALL_ASYNC_DELEGATE [as _callAsync] (E:...\node_modules\tapable\lib\Hook.js:18:14) at run (E:...\node_modules\webpack\lib\Watching.js:138:33) at E:...\node_modules\webpack\lib\Watching.js:120:6 at Compiler.readRecords (E:...\node_modules\webpack\lib\Compiler.js:908:11) at run (E:...\node_modules\webpack\lib\Watching.js:116:26) at E:...\node_modules\webpack\lib\Watching.js:112:6 at E:...\node_modules\webpack\lib\HookWebpackError.js:69:3 at E:...Hook.eval [as callAsync] (eval at create (\node_modules\tapable\lib\HookCodeFactory .js:33:10), :6:1)
-- package.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');
});
-- Folder structure --
Solution 1:[1]
This trouble from the ts-loader
. You can see pull request here.
Instead of using ts-loader you should use babel. You need change handlers .ts and .js in webpack config.
{
test: /\.[tj]sx?$/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env', '@babel/preset-react']
}
}
}
Also add .babelrc with this:
{"presets": ["@babel/react", "@babel/typescript", ["@babel/env", { "modules": false }]]}
Solution 2:[2]
TypeError: times is not iterable
Other than the fact that I'm confused as to why you're using serverside react rendering (unless you are trying out the experimental serverside react components), then you either need to modify your code in accordance with the above error or make times
iterable.
ES2015.Iterable defines that as
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>;
}
Where this will likely be of most use to you:
const times = 'StackOverflow'
const iterable = [...Array(...times).values()]
console.log(iterable);
This outputs each subcharacter as follows:
[LOG]: ["S", "t", "a", "c", "k", "O", "v", "e", "r", "f", "l", "o", "w"]
if you don't spread ...times
and instead use times
it outputs the string as it's defined by const times
. Alternatively, you could use a number in place of a string, such as 100. Then, it would return
[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]
if you want a countdown, then write
const times = 101
const iterable = [...Array(times).keys()].reverse();
The above outputs a countdown from 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]
Anyway, you could make whatever times
is Iterable, but it is worth noting that you're missing ts-node
as a dependency and that should be used if you're using an express server.
Solution 3:[3]
I had the same problem using ts-loader and webpack 5. It was resolved like this:
- win+r -> %temp% and cleared this folder
- Created a new folder for the project where I moved the sources and package.json
- In the new folder, I installed all the dependencies from package.json via "npm i" (without arguments)
Below is my package.the json on which this was done.
{
"name": "prj-dev-1",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build:dev": "cross-env NODE_ENV=development webpack --config webpack.config.js",
"build:prod": "cross-env NODE_ENV=production webpack --config webpack.config.js",
"dev": "cross-env NODE_ENV=development webpack-dev-server"
},
"author": "",
"license": "ISC",
"dependencies": {
"react": "^17.0.2",
"react-dom": "^17.0.2"
},
"devDependencies": {
"cross-env": "^7.0.3",
"html-webpack-plugin": "^5.5.0",
"ts-loader": "^9.2.6",
"typescript": "^4.5.5",
"webpack": "^5.69.0",
"webpack-cli": "^4.9.2",
"webpack-dev-server": "^4.7.4"
}
}
If you start the server via node bin\dev.js and this error persists, then try to do so:
Install npm i -D nodemon-webpack-plugin
Add settings for it in webpack.server.config.js
watch: true, plugins: [ new NodemonPlugin({ watch: path.resolve(__dirname, '../dist/server/server.js') }), // Dong ],
run "npx webpack --config webpack.config.js" ("node bin\dev.js" instead)
Solution 4:[4]
Just update version ts-loader to 9.2.8
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Aw3same |
Solution 2 | Andrew Ross |
Solution 3 | |
Solution 4 | ??????? ??????? |