HassanShakur
HassanShakur

Reputation: 121

sql.js throwing a "TypeError: Cannot set properties of undefined (setting 'exports')" in NextJS

I am trying to use sql.js to execute some sql code on the web using NextJS. So I created this server action function that just initializes the sql.js database.

'use server';

import initSqlJs from 'sql.js';

export const initDb = async () => {
  try {
    const SQL = await initSqlJs();
    const db = new SQL.Database();
    console.log(db);
  } catch (error) {
    console.error(error);
  }
};

Then in some other client component, I am just calling the function:

initDb().then((res) => {
  console.log(res);
});

This second code is never reached, meaning the server function throws an exception:

TypeError: Cannot set properties of undefined (setting 'exports')
    at eval (webpack-internal:///(action-browser)/./node_modules/sql.js/dist/sql-wasm.js:630:38)
    at new Promise (<anonymous>)
    at initSqlJs (webpack-internal:///(action-browser)/./node_modules/sql.js/dist/sql-wasm.js:19:24)
    at getUsers (webpack-internal:///(action-browser)/./app/actions/index.ts:18:72)
    at endpoint (webpack-internal:///(action-browser)/./node_modules/next/dist/build/webpack/loaders/next-flight-action-entry-loader.js?actions=%5B%5B%22C%3A%5C%5CUsers%5C%5CHassan%5C%5CDevelopment%5C%5CReact%5C%5CImplementation%5C%5Csql-visual%5C%5Capp%5C%5Cactions%5C%5Cindex.ts%22%2C%5B%22getUsers%22%5D%5D%5D&__client_imported__=true!:8:17)...

I expected in the least for the db to be logged to the console so I can access it, but no.

A pointer to the right direction will be appreciated.

Upvotes: 0

Views: 203

Answers (1)

HassanShakur
HassanShakur

Reputation: 121

This was a tricky one. Apparently, the server component backend dependency (sql.js) was included in the frontend bundle. Since it has node-specific features, this was causing some issues.

Found this article in the Next.js docs that configures it to exclude backend dependencies 👉 Server components external packages.

You therefore only need to edit the next.config.mjs file and add the serverComponentsExternalPackages as described in the docs.

/** @type {import('next').NextConfig} */
const nextConfig = {
  experimental: {
    // add the list of backend dependencies
    serverComponentsExternalPackages: ['sql.js'],
  },
};

export default nextConfig;

This can be done for any other backend dependency. Hope it helps someone.

Upvotes: 0

Related Questions