api icon indicating copy to clipboard operation
api copied to clipboard

Issue with NestJS

Open bennettl opened this issue 2 years ago • 24 comments

Trying to use this for my NestJS project, and when running got the following compilation error

import type * as types from './types'; ^^^^^^

SyntaxError: Cannot use import statement outside a module

It seems like this sits outside the src folder, not sure if it can be an issue. Any help is appreciated!!!

bennettl avatar Jan 12 '23 07:01 bennettl

I'm not at all familiar with NestJS but I have some questions about your install.

  1. How did you install your API SDK?
  2. Did you install it as JS or TypeScript?
  3. CJS or ESM?
  4. How are you loading your API SDK?

erunion avatar Jan 13 '23 23:01 erunion

edited: The problem seems to be that nest dist output main.js file is trying to access the ts file com the .app folder... So since js is trying to access a ts file it doesnt work. I could get it partially fixed using ts-node to run the main.js file

Im also having this problem after adding resolveJsonModule to my ts.config to fix the json import from the generated .api folder.

Answering @erunion

  1. npx api install @open-api-docs/MYAPI
  2. Typescript
  3. When running on typescript it doesnt ask that actually but on tsconfig is commonjs
  4. importing it directly from the generated .api folder

murtinha avatar Feb 02 '23 18:02 murtinha

I don't use NestJS so I'm not sure how to solve this. Do you know why it's trying to use the TS file directly instead of compiling it into your app when you build your main output main.js file?

erunion avatar Feb 02 '23 21:02 erunion

Probably because the .api directory is not being included in the build phase.

linzera avatar Feb 02 '23 21:02 linzera

Im not 100% sure but it seems to have to do with nest dependency injection

murtinha avatar Feb 04 '23 15:02 murtinha

This is the same issue in next.js

Cmoen11 avatar Feb 06 '23 20:02 Cmoen11

For what it's worth, if you're generating a JS SDK api will still generate TS types for you to use in local development. You don't need to generate a TS SDK to get TS types.

As for why Nest and Next aren't factoring these non-d.ts .ts files into your compilation processes I'm not sure.

erunion avatar Feb 07 '23 18:02 erunion

An update, if i run yarn install after i have generated the .api folder, I get these errors locally as well. It works again if I delete the folder and generate them once more.. @erunion

Cmoen11 avatar Feb 22 '23 10:02 Cmoen11

Alright, @erunion I think I've found out what's causing this. And it is neither next.js nor nuxt.js, it is for the project which uses yarn instead of npm.

It seems like the lib is forcing on npm, and it's creating conflicting package-lock.json with the yarn.lock file. switching over to npm instead seems to solve my problem.

Cmoen11 avatar Feb 24 '23 23:02 Cmoen11

I think i've located the problem.

https://github.com/readmeio/api/blob/ebb90af3605cb522f4aafaba75b9c9fe581b6534/packages/api/src/cli/codegen/languages/typescript.ts#LL156C21-L156C21

So if you're using a different package manager you may stumble on some problems caused by this.

Cmoen11 avatar Feb 24 '23 23:02 Cmoen11

Besides @Cmoen11, is everyone else in this thread using Yarn?

erunion avatar Feb 27 '23 18:02 erunion

Alright, so, I ran into this one today. Can confirm, not using Yarn, not using Nest or Next or anything, just plain node.

Got around this issue by copy-pasting the generated code from the .api folder to a new api folder in my src directory, and importing it directly (so, import x from '../api/apis/example' rather than import x from '@api/example') Interested to see how this could be avoided in future.

Pretty sure it has to do with tsconfig and module resolution

afreemanio avatar Mar 13 '23 22:03 afreemanio

Also with issues when need to use client side nextjs. Have tried several things, but it keeps trying to import fs library, that is not available for browsers. Just importing an sdk object causes: image

yangricardo avatar Mar 17 '23 01:03 yangricardo

@yangricardo That prepareParams file uses fs in order to handle file uploads through SDKs. If you're just using this in the browser you should be able to safely polyfill fs in your Webpack config.

https://stackoverflow.com/questions/64926174/module-not-found-cant-resolve-fs-in-next-js-application

erunion avatar Mar 17 '23 07:03 erunion

@afreemanio Would you be willing to share a working broken example of this in an isolated repository that I can play around with? Would be immensely helpful in figuring out what the heck the library is doing that's causing this.

erunion avatar Mar 17 '23 07:03 erunion

There may be multiple issues here. I use it server side, and I did not get this issue at first, but when I did yarn install to install another package. the problem occurred server side. I was deleting the .API folder and reinit the API SDK at it was working again.

also my deployment on vercel got this problem when vercel did yarn install instead of npm install.

When switching over to npm, all these problem was removed.

Cmoen11 avatar Mar 17 '23 07:03 Cmoen11

@yangricardo That prepareParams file uses fs in order to handle file uploads through SDKs. If you're just using this in the browser you should be able to safely polyfill fs in your Webpack config.

https://stackoverflow.com/questions/64926174/module-not-found-cant-resolve-fs-in-next-js-application

@erunion , i have already tried that, but it keeps trying to access fs functionalities...

image

yangricardo avatar Mar 17 '23 13:03 yangricardo

@afreemanio Would you be willing to share a working broken example of this in an isolated repository that I can play around with? Would be immensely helpful in figuring out what the heck the library is doing that's causing this.

https://github.com/afreemanio/api-604

As an update, looks like this is an issue for me specifically with ts-node (building and running normally seems to work fine). This might be related to other peoples issues, depending on the tool used to run the different frameworks.

I also ran into a few pain points when trying to use this library for the first time, so it might be worth considering having the option to install not as a separate package but as a subdirectory as I posted above. I was also running into some pain points with getting the ActiveCampaign API to install, and I think changes to the docs might be able to make things more clear for new users (I'd love to help). I'm considering opening another issue for these - you can see more details my README.md and notes.md file from the repo above.

afreemanio avatar Mar 20 '23 18:03 afreemanio

Got the same issues with yarn, nextjs, typescript target. Had to add the generated module to transpilePackages, then update webpack config to replace fs with an empty implementation. But now it's still failing because datauri seems to use fs/promises

nextjs config:

transpilePackages: ['@api/center-api'],
webpack(config) {
  config.resolve.fallback = {
    ...config.resolve.fallback,
    fs: false,
  }

  return config
},

maggo avatar Apr 20 '23 17:04 maggo

For anyone using Vite, this works:

import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react-swc'
import { nodePolyfills } from "vite-plugin-node-polyfills";

// https://vitejs.dev/config/
export default defineConfig({
    plugins: [
        react(),
        nodePolyfills({
            // To exclude specific polyfills, add them to this list.
            exclude: [
                'fs', // Excludes the polyfill for `fs` and `node:fs` (which is empty)
            ],
            // Whether to polyfill `node:` protocol imports.
            protocolImports: true,
        }),
    ],
    resolve: {
        alias: {
            // The fs polyfill in vite-plugin-node-polyfills is empty; use this, which contains promises needed by datauri
            fs: 'memfs'
        }
    }
});

JPCanaverde avatar May 04 '23 01:05 JPCanaverde

Had the same issue with Nest.js and yarn, when generating a typescript version of code. Switched to the JS version and it works fine, types are still there.

I think it happens because the generated TS code lands to node_modules, but default TS config in Nest.js doesn't compile TS files in node_modules. Probably could be solved by changing tsconfig file. But as JS version works well, I don't care.

pnedelko avatar May 30 '23 19:05 pnedelko

The original error is due to trying to load ESM in a CommonJS environment. Even with node 18 it requires many hoops to get ESM running and I don't recommend it given the ecosystem is a nightmare of blood, sweat, and tears; it's a time sink in terms of Jest + TS + ESM to get things working properly.

This is a classic error in the node ecosystem trying to import an ESM module outside of your build pipeline [of ESM -> Common JS]. We all often write ESM, but there's normally some transpilation step that turns it into Common JS before loading it through node whether that be Vite, SWC, TS-Node, TS-Jest, etc. You could likely get this working by including the .api directory into the tsconfig includes section to make it part of the transpilation from ESM to Common JS.

As for the fs not found on client-side code that's another problem [given fs is for the server-side] :P

ctsstc avatar Aug 11 '23 22:08 ctsstc

Hey folks 👋🏽 we've been cooking up some exciting stuff for the next major release of api and we'd love if you could provide us with feedback! We've overhauled our code generation strategy so you no longer have to specify your SDK type (ESM, CommonJS, TS, etc.). Thanks to a new build/export strategy that leverages tsup, it should hopefully just work in your modern[^1] JS environment of choice, including NestJS! You can test it out now by running the following:

npx api@next install [your API definition here]

We'd love to hear what you think over at https://github.com/readmeio/api/discussions/791, where I also wrote up a little preview of all the changes coming in api v7 👀

Just note that it's still in beta so we don't recommend using this in production since we may ship more breaking changes as we approach a general release. Thanks y'all!

[^1]: Note that api now requires Node.js v18 or greater if you're a Node.js user, and TypeScript 5.2 if you're a TypeScript user.

kanadgupta avatar Oct 26 '23 16:10 kanadgupta

Got the same issues with yarn, nextjs, typescript target. Had to add the generated module to transpilePackages, then update webpack config to replace fs with an empty implementation. But now it's still failing because datauri seems to use fs/promises

nextjs config:

transpilePackages: ['@api/center-api'],
webpack(config) {
  config.resolve.fallback = {
    ...config.resolve.fallback,
    fs: false,
  }

  return config
},

@maggo A simple workaround to solve this issue is to create a file named fs-polyfill.js in your root directory (or any other preferred location), containing the following content:

module.exports = { promises: { readFile: {} } };

and inside the next.config.js file add:

transpilePackages: ['@api/center-api'],
webpack(config) {
  config.resolve.fallback = {
    ...config.resolve.fallback,
    fs: path.join(__dirname, "fs-polyfill.js"),
  }
  return config
},

chelorope avatar Apr 16 '24 23:04 chelorope