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

31 views Asked by At

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.

1

There are 1 answers

0
HassanShakur On

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.