zenstack icon indicating copy to clipboard operation
zenstack copied to clipboard

[Feature Request] ESM support

Open ymc9 opened this issue 1 year ago • 8 comments

Reported by VT01 on discord.

import { ZenStackMiddleware } from '@zenstackhq/server/express';
Error:
SyntaxError: Named export 'ZenStackMiddleware' not found. The requested module '@zenstackhq/server/express' is a CommonJS module, which may not support all module.exports as named exports.
CommonJS modules can always be imported via the default export, for example using:

import pkg from '@zenstackhq/server/express';
const { ZenStackMiddleware } = pkg;

Node.js v20.11.0

my tsconfig.json:

"compilerOptions": { "target": "esnext", "module": "NodeNext", "moduleResolution": "NodeNext", "strict": true, "esModuleInterop": true, "skipLibCheck": true, "forceConsistentCasingInFileNames": true, "outDir": "./dist", "noUncheckedIndexedAccess": true, "lib": [ "ESNext" ], }

package.json fields that probably causes the mistake (however I need it): "type": "module"

ymc9 avatar Jan 29 '24 09:01 ymc9

we got this error

import { ZenStackMiddleware } from "@zenstackhq/server/express";
         ^

SyntaxError: The requested module '@zenstackhq/server/express' does not provide an export named 'ZenStackMiddleware'
    at ModuleJob._instantiate (node:internal/modules/esm/module_job:132:21)
    at async ModuleJob.run (node:internal/modules/esm/module_job:214:5)
    at async ModuleLoader.import (node:internal/modules/esm/loader:329:24)
    at <anonymous> (/home/tmax/development/try-mehadrin/packages/mehadrin-express/src/server.ts:8:17)

Node.js v20.11.1

so we can't use zenstack if our backend uses "type":"module" in package.json? any workarounds until v2.0.0? by the way I think this should be considered a first priority bug and not v2 milestone as es modules are the way to go even in backend environments in 2024

workaround for now

for now, we were able to import it using:

import { createRequire } from "module";
const require = createRequire(import.meta.url);
const { ZenStackMiddleware } = require("@zenstackhq/server/express");

you would also need "moduleResolution": "NodeNext" in tsconfig.json:

{
  "compilerOptions": {
    "module": "NodeNext",
    "esModuleInterop": true,
    "target": "esnext",
    "noImplicitAny": true,
    "moduleResolution": "NodeNext",
    "sourceMap": true,
    "outDir": "dist",
    "baseUrl": ".",
    "skipLibCheck": true,
    "strict": true
  },
  "include": ["src/**/*.ts"],
  "exclude": ["node_modules"]
}

tmax22 avatar Mar 18 '24 09:03 tmax22

Same issue for generated Zod schemas as well.

import { ModelUpdateScalarSchema } from "@zenstackhq/runtime/zod/models";
        ^^^^^^^^^^^^^^^^^^^^^
SyntaxError: Named export 'ModelUpdateScalarSchema' not found. The requested module '@zenstackhq/runtime/zod/models' is a CommonJS module, which may not support all module.exports as named exports.
CommonJS modules can always be imported via the default export, for example using:

import pkg from '@zenstackhq/runtime/zod/models';
const { ModelUpdateScalarSchema } = pkg;

sidharthv96 avatar May 28 '24 17:05 sidharthv96

we got this error

import { ZenStackMiddleware } from "@zenstackhq/server/express";
         ^

SyntaxError: The requested module '@zenstackhq/server/express' does not provide an export named 'ZenStackMiddleware'
    at ModuleJob._instantiate (node:internal/modules/esm/module_job:132:21)
    at async ModuleJob.run (node:internal/modules/esm/module_job:214:5)
    at async ModuleLoader.import (node:internal/modules/esm/loader:329:24)
    at <anonymous> (/home/tmax/development/try-mehadrin/packages/mehadrin-express/src/server.ts:8:17)

Node.js v20.11.1

so we can't use zenstack if our backend uses "type":"module" in package.json? any workarounds until v2.0.0? by the way I think this should be considered a first priority bug and not v2 milestone as es modules are the way to go even in backend environments in 2024

workaround for now

for now, we were able to import it using:

import { createRequire } from "module";
const require = createRequire(import.meta.url);
const { ZenStackMiddleware } = require("@zenstackhq/server/express");

you would also need "moduleResolution": "NodeNext" in tsconfig.json:

{
  "compilerOptions": {
    "module": "NodeNext",
    "esModuleInterop": true,
    "target": "esnext",
    "noImplicitAny": true,
    "moduleResolution": "NodeNext",
    "sourceMap": true,
    "outDir": "dist",
    "baseUrl": ".",
    "skipLibCheck": true,
    "strict": true
  },
  "include": ["src/**/*.ts"],
  "exclude": ["node_modules"]
}

Hi @tmax22 , sorry I missed this comment. Is this still an issue for you with v2?

ymc9 avatar May 29 '24 00:05 ymc9

Same issue for generated Zod schemas as well.

import { ModelUpdateScalarSchema } from "@zenstackhq/runtime/zod/models";
        ^^^^^^^^^^^^^^^^^^^^^
SyntaxError: Named export 'ModelUpdateScalarSchema' not found. The requested module '@zenstackhq/runtime/zod/models' is a CommonJS module, which may not support all module.exports as named exports.
CommonJS modules can always be imported via the default export, for example using:

import pkg from '@zenstackhq/runtime/zod/models';
const { ModelUpdateScalarSchema } = pkg;

Hi @sidharthv96 , did you get this when compiling generated trpc code? Is this still with a sveltekit project?

ymc9 avatar May 29 '24 00:05 ymc9

Sveltekit itself. I was using zod to validate our REST payload. It works fine locally, but fails to build in CI, when using a different adapter.

And we are on v2

sidharthv96 avatar May 29 '24 06:05 sidharthv96

actually, in v2, import { ZenStackMiddleware } from '@zenstackhq/server/express'; works just fine for me

tmax22 avatar May 30 '24 04:05 tmax22

Running into this myself as well, I'm on zenstack version: 2.2.4:

import { SomeSchema } from 'node_modules/@zenstackhq/runtime/zod/models.js';
         ^^^^^^^^^^^
  SyntaxError: The requested module 'node_modules/@zenstackhq/runtime/zod/models.js' does not provide an export named 'SomeSchema'
  at ModuleJob._instantiate (node:internal/modules/esm/module_job:134:21)
  at async ModuleJob.run (node:internal/modules/esm/module_job:217:5)
  at async ModuleLoader.import (node:internal/modules/esm/loader:323:24)
  at async loadESM (node:internal/process/esm_loader:28:7)
  at async handleMainPromise (node:internal/modules/run_main:120:12)
  ``

genu avatar Jun 27 '24 18:06 genu

A workaround, is to change the location where the zod generates the schemas; have it generate in your project the rather than node_modules

Mileage may vary, as you can run into other issues when you generate the zod schema in your own project as now those generated files are subject type checking

genu avatar Jun 27 '24 18:06 genu