keystonejs / keystone

The most powerful headless CMS for Node.js — built with GraphQL and React
https://keystonejs.com
MIT License
8.98k stars 1.13k forks source link

Unable to import native module #7291

Open JMLX42 opened 2 years ago

JMLX42 commented 2 years ago

How to reproduce

Attempt to import a module that will load a .node native module.

Expected behavior

The app builds and runs normally.

Actual behavior

Webpack complains there is no loader for the .node module:

yarn run v1.22.15
$ keystone dev
✨ Starting Keystone
⭐️ Dev Server Starting on http://localhost:3000
⭐️ GraphQL API Starting on http://localhost:3000/api/graphql
✨ Generating GraphQL and Prisma schemas
✨ The database is already in sync with the Prisma schema.
✨ Connecting to the database
✨ Creating server
✅ GraphQL API ready
✨ Generating Admin UI code
✨ Preparing Admin UI app
event - compiled client and server successfully in 10.4s (1500 modules)
Attention: Next.js now collects completely anonymous telemetry regarding usage.
This information is used to shape Next.js' roadmap and prioritize features.
You can learn more, including how to opt-out if you'd not like to participate in this anonymous program, by visiting the following URL:
https://nextjs.org/telemetry

✅ Admin UI ready
wait  - compiling /api/__keystone_api_build...
error - ../../../../usr/local/lib/node_modules/smartshape_license_nodejs/smartshape_license_nodejs.linux-x64-gnu.node
Module parse failed: Unexpected character '' (1:0)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders

I did not find how to customize Webpack in the KeystoneJS documentation.

JMLX42 commented 2 years ago
✅ Admin UI ready
wait  - compiling /api/__keystone_api_build...
error - ../../../../usr/local/lib/node_modules/smartshape_license_nodejs/smartshape_license_nodejs.linux-x64-gnu.node
Module parse failed: Unexpected character '' (1:0)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders

This is obviously an error thrown by Webpack. However, the import statement is in one the schemas. So I fail to understand how/why Webpack is running on the backend code.

My guess is NextJS is bundling using Webpack.

In the .keystone/admin folder generated for my project, I see a next.config.js file. It is apparently loading the NextJS configuration created here:

https://github.com/keystonejs/keystone/blob/3e538d1360add48c37a099de7c9d1621e2c74ddf/packages/core/src/___internal-do-not-use-will-break-in-patch/admin-ui/next-config.ts

Including the Webpack configuration:

https://github.com/keystonejs/keystone/blob/3e538d1360add48c37a099de7c9d1621e2c74ddf/packages/core/src/___internal-do-not-use-will-break-in-patch/admin-ui/next-config.ts

And there is apparently no way to customize it.

JMLX42 commented 2 years ago

Since Webpack will hijack any call to require(), here is the workaround I found:

const { myNativeFunction } = eval('require')('/path/to/native/module');

Then the require() in /path/to/native/module/index.js work as expected.

raveling commented 2 years ago

Thanks for this. It's a bug. We'll look into it.

linus-ha commented 5 months ago

This worked for me when building a custom field using uploaded data.

// run EXIF analysis
const meta = await (await import(/* webpackIgnore: true */ "./extractMeta")).extractMeta(upload.createReadStream());