Issue with NestJS
Opened this issue ยท 25 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!!!
I'm not at all familiar with NestJS but I have some questions about your install.
- How did you install your API SDK?
- Did you install it as JS or TypeScript?
- CJS or ESM?
- How are you loading your API SDK?
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
npx api install @open-api-docs/MYAPI
- Typescript
- When running on typescript it doesnt ask that actually but on tsconfig is commonjs
- importing it directly from the generated .api folder
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?
Probably because the .api
directory is not being included in the build phase.
Im not 100% sure but it seems to have to do with nest dependency injection
This is the same issue in next.js
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.
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
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.
I think i've located the problem.
So if you're using a different package manager you may stumble on some problems caused by this.
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
@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
@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.
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.
@yangricardo That
prepareParams
file usesfs
in order to handle file uploads through SDKs. If you're just using this in the browser you should be able to safely polyfillfs
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...
@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.
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
},
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'
}
}
});
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.
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
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 modern1 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 #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!
Footnotes
-
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. โฉ
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 becausedatauri
seems to usefs/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
},
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 innode_modules
. Probably could be solved by changing tsconfig file. But as JS version works well, I don't care.
thx for ur idea! after I chose js and add the "@api/xxx": "file:.api/apis/xxx"
in package.json
manually, everything works fine