Due to Joystick's dependency on Node.js v20+, imports are designed to work in-step with the default behavior of the runtime.
Joystick prior to RC1 implemented the experimental Node.js --experimental-specifier-resolution=node
flag when running your server. This enabled the ability for file paths like these to function:
/path/to/index
whereindex
was a file calledindex.js
. We could omit the.js
and Node would still resolve it./path/to/folder
where it was assumed anindex.js
file would be located at/path/to/folder/index.js
and Node would still resolve it.
After the move to Node.js v20+, this functionality no longer works. Instead, paths that are not pointed at a package in the /node_modules
directory are assumed to be relative to the current file in your app.
So for example, if we have a file like /lib/node/parse_markdown.js
and wanted to import that into our index.server.js
file, we'd do something like this:
index.server.js
import joystick from "@joystick.js/node-canary";
import api from "./api/index.js";
import parse_markdown from "./lib/node/parse_markdown.js";
joystick.app({
api,
routes: {
"/": (req = {}, res = {}) => {
res.render("ui/pages/index/index.js", {
layout: "ui/layouts/app/index.js",
});
},
"*": (req = {}, res = {}) => {
res.render("ui/pages/error/index.js", {
layout: "ui/layouts/app/index.js",
props: {
status_code: 404,
},
});
},
},
}).then(() => {
const markdown_test = parse_markdown(`## Testing 123`);
console.log(markdown_test);
});
Here, notice the path for the parse_markdown.js
file is both:
- The relative path (again, relative to the
index.server.js
file) to the file. - Uses the full file path, including the
.js
suffix on the file path.
If we were to omit the .js
, Joystick would still be able to resolve the path, however, it would not trigger any hot module reloading (HMR) behavior in Joystick. If we were to omit the /index.js
part entirely, Joystick would be unable to resolve the path.