Can't use external node modules with docker

Hi all,
I’m trying to use nanoid npm module inside a function node, but I always get
VMError: Failed to load 'nanoid': Unknown type.

I customized the build of the container this way:

FROM n8nio/n8n:latest
npm install nanoid -g
CMD ["n8n"]

and added the allow external to docker-compose.yml (I added NODE_PATH also, but it doesn’t resolve the issue)

- NODE_FUNCTION_ALLOW_EXTERNAL=nanoid
- NODE_PATH=/usr/local/lib/node_modules

Obvioulsly, I rebuilt the container and reloaded it.

This is the node code:

const {nanoid} = require('nanoid');
const id = nanoid();

It works inside a .js file launched with node test.js but it doesn’t find the module in the n8n sandboxed loader.

Any help?

TIA in advance!

The package has to be listed in /{{root directory}}/packages/nodes-base/package.json

Hi Ricardo, thanks for your answer!
I can’t understand where and how I have to list the package, because I have no packages directory inside the n8n container. Can you please detail a bit more to help me understand better?
Thank you for your support!

In the example you showed me above, you are installing the package in the root directory. In order for the node to access the package “nanoid” you need to add the dependency in the node-base directory. Check the link below.

Hi Ricardo, this is much more clear now.
I will take a look at the complete custom rebuilt, but I solved by switching to uuid at the moment.

I didn’t just install the package in the root directory, I installed it globally, which makes it available in /usr/local/lib/node_modules. This works perfectly well for other packages like uuid and moment

I don’t understand what is the difference between these two packages in terms of loading and I suppose there is something happening in the sandbox.js. The only difference I know about is that nanoid requires crypto and uuid doesn’t have dependencies. But, I whitelisted all the builtins… No changes.
dayjs also works fine with this method.

@lucabartoli @RicardoE105 I’ve now come across the same issue, with another npm module.

My setup: docker based (custom image)
Dockerfile-

FROM n8nio/n8n:latest

RUN apk add --update python3 py3-pip
RUN npm install -g require
RUN npm install -g he
RUN npm install -g uuid
...
RUN npm install -g emailjs --save
RUN npm install -g dayjs
RUN npm update -g --dev

This is the first time i’ve come across this error, for any of the installed npm modules:

Stack
VMError: Failed to load 'emailjs': Unknown type.
    at _require (/usr/local/lib/node_modules/n8n/node_modules/vm2/lib/sandbox.js:410:10)
    at /usr/local/lib/node_modules/n8n/node_modules/n8n-nodes-base/dist/nodes:1:121
    at Object.<anonymous> (/usr/local/lib/node_modules/n8n/node_modules/n8n-nodes-base/dist/nodes:33:2)
    at NodeVM.run (/usr/local/lib/node_modules/n8n/node_modules/vm2/lib/main.js:1167:29)
    at Object.execute (/usr/local/lib/node_modules/n8n/node_modules/n8n-nodes-base/dist/nodes/Function.node.js:81:31)
    at Workflow.runNode (/usr/local/lib/node_modules/n8n/node_modules/n8n-workflow/dist/src/Workflow.js:492:37)
    at /usr/local/lib/node_modules/n8n/node_modules/n8n-core/dist/src/WorkflowExecute.js:424:62

Unable to figure out the reason.

It might be because emailjs is written in typescript. Not sure if the function node is configured to support ts modules. @jan should have a better insight than me.