Problems when bundling a express/sequelize/sqlite app using esbuild

154 Views Asked by At

Edit

I've been bamboozled with regards to the sequelize part. The person responsible by connecting the gateway was pointing to an old endpoint and the answer was returning wrong as a result. I was also my fault as I've only tested using the gateway instead of directy, neither I've properly monitored the logs.

Still don't know how to solve the sqlite part though, would be grateful if anyone was able to shine a light on it. Even if the light is "it's not possible because..."

Original

I've been running into a wall when trying to bundle a express app so that I don't have to spend ~200MB of storage solely on node_modules. Therefore I've come here in other to ask for help. The problem comes from the sequelize and sqlite3 modules, as they don't seem to work as intented.

With regards to Sqlite

This one is a little bit simpler to explain. Basically, the bundled .js file do not have the sqlite3 module itself.

I've tried explicitly requiring the module and even passing to the property dialectModule: of the sequelize instance. If I do so with the package itself it will run into a variety of dependency problems that once resolved outputs this:

Error: express-api-starter-ts package.json is not node-pre-gyp ready:
package.json must declare these properties:
binary
    at Object.gRe [as validate_config] (path\dist\index.js:137:219)
    at HM.find (path\dist\index.js:404:8282)
    at path\dist\index.js:406:166
    at path\dist\index.js:1:356
    at path\dist\index.js:411:108
    at path\dist\index.js:1:356
    at Object.<anonymous> (path\dist\index.js:413:12918)
    at Module._compile (node:internal/modules/cjs/loader:1241:14)
    at Module._extensions..js (node:internal/modules/cjs/loader:1295:10)
    at Module.load (node:internal/modules/cjs/loader:1091:32)

I've also tried compiling the node_sqlite3 module into a .node file and passing onto the same property with a default esbuild .node loader (don't know if I misconfigured though) and got a this.lib.Database is not a constructor error.

So I sort and gave up and just installed the module in a node_module package on the server and let it run normally. It worked, but it was not as I wished.

With regards to Sequelize

Once I've sorted the previous issue and got the app running I've noticed that the REST request was returning me an answer without taking into account the models defined by sequelized. In other words, if the structured defined by sequelize in code was:

  "name": "John",
  "phone": "99999999",
  "birthdate": 23102020

the answers was being returned as (the same column name present in the database):

  "NAME": "John",
  "PHONE": "99999999",
  "BIRTHDATE": 23102020

Closing thoughts

I wish to know if anyone has gone through this situation before or something similar and has an answer on how to solve it.

The command I've been using to bundle is: esbuild src/index.ts --platform=node --loader:.node=file --bundle --minify --outfile=dist/index.js

1

There are 1 best solutions below

0
On

You might want to look into marking the libraries that cannot be found as external. Check the documentation for esbuild on external.

Here is an example of how such a build script can look like:

const { build } = require('esbuild')
const glob = require('glob')
const entryPoints = glob.sync('./src/**/*.{ts,js}')

build({
  entryPoints,
  outbase: './src',
  outdir: './dist' ,
  platform: 'node',
  minify: true,
  bundle: true,
  external: ["pg-hstore", "aws-sdk", "lambda-core", "lambda-dal"] // Here you would put your library name that you want to ignore
})