I am using socket.IO running in Express to distribute data among clients. To gain that data I need to use a function from another file. Now if I understand it correctly Node + Express doesn't natively support import / export key words, which I am using in the client (React) side of the app. Because of that I have used "require" inside the server file:
server.js
const initialStateFunctions = require("../components/functions/InitialStateFunctions");
const playerStates = initialStateFunctions.getInitialPlayerStates();
InitialStateFunctions.js
import {shuffleArray} from "./CardManipulationFuntions";
import {ARTIFACTS, CARD_STATE, CARD_TYPE, GUARDIANS, ITEMS} from "../../data/cards";
import {GLOBAL_VARS} from "../../App";
import {LOCATION_LEVEL, LOCATION_STATE, LOCATIONS} from "../../data/locations";
/* INITIAL PLAYER STATE */
export function getInitialPlayerStates() {
However now Express doesn't load because of this error:
> lore_hunters@0.1.0 start C:\Projects\lore_hunters
> node src/server/server.js
C:\Projects\lore_hunters\src\components\functions\InitialStateFunctions.js:1
import {shuffleArray} from "./CardManipulationFuntions";
^^^^^^
SyntaxError: Cannot use import statement outside a module
at wrapSafe (internal/modules/cjs/loader.js:1063:16)
at Module._compile (internal/modules/cjs/loader.js:1111:27)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1167:10)
at Module.load (internal/modules/cjs/loader.js:996:32)
at Function.Module._load (internal/modules/cjs/loader.js:896:14)
at Module.require (internal/modules/cjs/loader.js:1036:19)
at require (internal/modules/cjs/helpers.js:72:18)
at Object.<anonymous> (C:\Projects\lore_hunters\src\server\server.js:11:32)
at Module._compile (internal/modules/cjs/loader.js:1147:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1167:10)
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! lore_hunters@0.1.0 start: `node src/server/server.js`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the lore_hunters@0.1.0 start script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
I would like to retain using import / export modules in InitialStatesFunction - how then should I import the getInitialPlayerState function into the server.js application? Do I need to somehow turn server.js to a module? (" Cannot use import statement outside a module")
EDIT: I understand that Node doesn't natively use import
and the require
is to be used. The problem is that the loaded module than returned the error I have listed in my question.
EDIT2: When using "type": "module" option for the newer version of Node, I can rewrite the server.js file to use imports instead of requires:
import express from "express";
import http from "http"
import socketIO from "socket.io"
import path from "path"
import {getInitialPlayerStates} from "../components/functions/InitialStateFunctions";
const port = process.env.PORT || 4001;
const app = express();
// server instance
const server = http.createServer(app);
const playerStates = getInitialPlayerStates();
However this thows following error:
(node:12816) ExperimentalWarning: The ESM module loader is experimental.
internal/modules/esm/resolve.js:61
let url = moduleWrapResolve(specifier, parentURL);
^
Error: Cannot find module C:\Projects\lore_hunters\src\components\functions\InitialStateFunctions imported from C:\Projects\lore_hunters\src\server\server.js
at Loader.defaultResolve [as _resolve] (internal/modules/esm/resolve.js:61:13)
at Loader.resolve (internal/modules/esm/loader.js:85:40)
at Loader.getModuleJob (internal/modules/esm/loader.js:191:28)
at ModuleWrap.<anonymous> (internal/modules/esm/module_job.js:42:40)
at link (internal/modules/esm/module_job.js:41:36) {
code: 'ERR_MODULE_NOT_FOUND'
}
The path shown in the output seemes to be correct. The folder structure follows:
EDIT: it seems that imports have to have file extension specified (https://medium.com/@nodejs/announcing-core-node-js-support-for-ecmascript-modules-c5d6dc29b663) - that was easy to fix, however then the server has problem with JSX:
effectsText: <Coin/>,
^
SyntaxError: Unexpected token '<'