Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Module not found: Can't resolve 'tedious' #195

Closed
maral opened this issue Jun 2, 2023 · 8 comments
Closed

Module not found: Can't resolve 'tedious' #195

maral opened this issue Jun 2, 2023 · 8 comments
Assignees

Comments

@maral
Copy link
Contributor

maral commented Jun 2, 2023

Describe the bug
I want to use remult in my Next.js app router app. This is /src/app/api/[...remult]/route.ts:

import { Region } from "@/entities/Region";
import { remultNextApp } from "remult/remult-next";
import { createKnexDataProvider } from "remult/remult-knex";

export const api = remultNextApp({
  entities: [Region],
  dataProvider: createKnexDataProvider({
    client: "sqlite3",
    connection: {
      filename: "./data/address_points.db"
    },
  }),
});

export const { GET, POST, PUT, DELETE } = api;

When I run curl http://localhost:3000/api/regions -H "Content-Type: application/json" I get the following error printed into the console:

- error ./node_modules/knex/lib/dialects/mssql/index.js:89:16
Module not found: Can't resolve 'tedious'

https://nextjs.org/docs/messages/module-not-found

Import trace for requested module:
./node_modules/knex/lib/dialects/index.js
./node_modules/knex/lib/knex-builder/internal/config-resolver.js
./node_modules/knex/lib/knex-builder/Knex.js
./node_modules/knex/lib/index.js
./node_modules/knex/knex.js
./node_modules/remult/remult-knex/index.js
./src/app/api/[...remult]/route.ts

Apparently knex does not understand I want SQLite and tries to import every driver possible. When I installed tedious, the error changed to 'mysql'...

I pushed it to a new branch in my repo here: https://github.com/maral/catchment-areas/tree/add-text-to-map-and-remult

What do I do differently to the tutorials? :(((

@maral
Copy link
Contributor Author

maral commented Jun 3, 2023

So I really don't understand how this works, but I found a solution here:
knex/knex#3727

I changed my (previously empty) next.config.js like this:

/** @type {import('next').NextConfig} */
const nextConfig = {
  webpack: (config) => {
    config.externals = ['knex','sqlite3'];
    return config;
  },
}

module.exports = nextConfig

And it started working... 🤔 How, I have no idea.

@maral
Copy link
Contributor Author

maral commented Jun 4, 2023

So actually my previous fix broke my Next.js app 😆 I started getting these errors seemingly out of nowhere:

Warning: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
1. You might have mismatching versions of React and the renderer (such as React DOM)
2. You might be breaking the Rules of Hooks
3. You might have more than one copy of React in the same app
See https://reactjs.org/link/invalid-hook-call for tips about how to debug and fix this problem.
- error node_modules\next\dist\compiled\react\cjs\react.development.js (1752:0) @ useContext
- error TypeError: Cannot read properties of null (reading 'useContext')

So if anyone stumbles upon this, I had to change it not to overwrite the previously set config.externals:

/** @type {import('next').NextConfig} */
const nextConfig = {
  webpack: (config) => {
    config.externals = [ ...config.externals, 'knex', 'sqlite3' ];
    return config;
  },
}

module.exports = nextConfig

@maral
Copy link
Contributor Author

maral commented Jun 4, 2023

And now the whole app is unresponsive (just gets stuck in some react-dom code without actually doing anything, hot reload does not work) and does not work properly... 😞 So I still have no idea what the solution is.

@yoni-rapoport
Copy link
Collaborator

I'm still looking at your original issue with "Module not found: Can't resolve 'tedious'".

Trying to figure out if there's another way to handle it...

@yoni-rapoport
Copy link
Collaborator

This worked for me:

knex/knex#1128 (comment)

/** @type {import('next').NextConfig} */
const nextConfig = {
  experimental: {
    serverComponentsExternalPackages: ['knex'],
  },
};

module.exports = nextConfig;

@maral
Copy link
Contributor Author

maral commented Jun 4, 2023

Great! This is exactly what I needed. My last mentioned errors were unrelated, it became unresponsive after I left async in front of the main page component function.

I am just wondering - is it now possible to use remult inside server components, like this?
https://nextjs.org/docs/app/building-your-application/data-fetching/fetching#async-and-await-in-server-components

When I tried that (like this):

const countiesRepo = remult.repo(County);

export default async function Home() {
  const counties = await countiesRepo.find();
  return <Something data={counties}
}

I got this error:

Error: remult object was requested outside of a valid context, try running it within initApi or a remult request cycle

As for this issue, you can close it, but maybe it would be useful to add a note to the documentation.

@yoni-rapoport
Copy link
Collaborator

yoni-rapoport commented Jun 4, 2023

To use remult in custom (server-side) code you need to wrap your code with api.withRemult middleware function.

import { api } from "./api/[...remult]/route";

const countiesRepo = remult.repo(County);

export default async function Home() {
  const counties = api.withRemult(async () => await countiesRepo.find());
  return <Something data={counties}
}

@stevenpalma123
Copy link

might be helpful:

@mikro-orm/core
@mikro-orm/knex

https://nextjs.org/docs/app/api-reference/next-config-js/serverComponentsExternalPackages

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants