[HELP] Not been able to import external modules

No I am not modifying any UI. I want to use it inside Function-node just like we’d do in any Javascript file. I’ve tried writing this simple line of code and it doesn’t seem to be working.

@chinmay_chavan working on a node that format dates so that you do not have to import any packages. Is that the use case you are looking for?

1 Like

No not really, that was just trial and error. For my use case I want to import built.io package from npmjs.com.

@chinmay_chavan did play around with it two days ago and now today again. Sadly does now work like expected. It works fine in the dev-environment but not when installed regularly. Hope I can figure out the problem soon.

1 Like

Ok did figure out the issue. I did actually already find it two days ago but never worked in my tests anyway (which confused me a lot). I just found out why. I always changed the code in the Function-Node but my test workflow had the FunctionItem-Node. Totally stupid!!! Hours waisted for nothing. Anway is fixed now and will be released with the next version.

1 Like

Ok released now [email protected] with the fix.

Just tested like that and it works now fine:

# Go in folder you want to install n8n in and install n8n with the modules you need
npm install n8n moment
# Allow access to the modules
export NODE_FUNCTION_ALLOW_EXTERNAL=moment
# Start n8n
node node_modules/.bin/n8n
1 Like

Could you suggest a way I can make this work with the Docker container, please? Or, will this only work with standalone installs?

Haha! We’ve all been there mate! Thank you for taking out the time to work on this and making it work! :slight_smile: Kudos!

I’ll try this out and get back here, Thanks once again!

It is theoretically also possible with the docker image but much more messy as you have to mount each module you need separate. For “sugar-date” that would for example additionally be “sugar-core” as “sugar-'date” depends on it. The more complex the module you need the more modules that would be. So for it to work you would have to:

  1. npm install “sugar-date” (or whatever you want) in a folder (in this example it would be ~/whereever-you-have-the-module)
  2. Then start the n8n container kind of like this:
docker run -it --rm \
  --name n8n \
  -p 5678:5678 \
  -e NODE_FUNCTION_ALLOW_EXTERNAL=sugar-date \
  -v ~/.n8n:/root/.n8n \
  -v ~/whereever-you-have-the-module/node_modules/sugar-core:/usr/local/lib/node_modules/sugar-core \
  -v ~/whereever-you-have-the-module/node_modules/sugar-date:/usr/local/lib/node_modules/sugar-date \
  n8nio/n8n:0.51.0
1 Like

That worked perfectly! Thanks a lot, @jan. :slight_smile:
Will stick to the Docker container for now and then move on to a native install if I end up needing lots of such modules.

Great to hear that it worked! Wish you a great day!

1 Like

For anyone wondering how to allow multiple, just put them in a comma separated list like so

export NODE_FUNCTION_ALLOW_EXTERNAL=moment,date-fns,feiertagejs

(as a multiple export of the single value will obviously override the previous one)
Great feature, thanks

EDIT:
For those who want to use date-fns and date-fns-tz (tz stands for timezone), in order to have it fully supported ( full-icu)you need nodejs > 13. I ran into an issue:

The module ‘/var/www/vhosts/rz.gl/mat.rz.gl/node_modules/mmmagic/build/Release/magic.node’
was compiled against a different Node.js version using
NODE_MODULE_VERSION 72.

I solved it by first updating nodejs and npm to latest version and then running

npm rebuild mmmagic--update-binary
5 Likes

Hey Jan!

Is this still working in version 0.112.0? I updated my docker-compose.yml file and .env file with your suggestion but still get a permission error.

docker-compose.yml
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- ${DATA_FOLDER}/.n8n:/home/node/.n8n
- /root/node_modules/sugar-core:/usr/local/lib/node_modules/sugar-core
- /root/node_modules/sugar-date:/usr/local/lib/node_modules/sugar-date
- /root/node_modules/moment:/usr/local/lib/node_modules/moment

.env
# Allow external NPM modules
NODE_FUNCTION_ALLOW_EXTERNAL=moment,sugar-date

error

Thank you :slight_smile:

Welcome to the community @replwithoutacause!

Do not think variables that are defined in the .env file will automatically be set by default in all containers defined in the docker-compose.yml file. To not having to go into to much detail it is proably best you set it directly in that file.

Btw. sugar-date will not work as all that this variable does is to allow access to modules that are installed and so available. So if you want to also be able to use that module you have to build a custom docker image which also installs that additionally.

1 Like

I tried setting everything in the docker-compose.yml file too but still couldn’t get it working.

I’m sorry, I’m not clear on your comment regarding sugar-date because based on the replies above it looks like it should work. Is sugar-date different than moment? I thought they were both considered external modules? I should have mentioned I did a npm install on both moment and sugar-date which is why I thought I could use them.

Thanks for n8n, by the way. It is a great platform!

Would you mind having a look at my config below to see if anything incorrect jumps out at you? It seemed correct to me after reading over this thread and the n8n documentation. However, I realize I probably don’t need NODE_FUNCTION_ALLOW_EXTERNAL=moment,sugar-date in both the docker-compose.yml and .env files, but I was experimenting to try to get it working.

You can see I have the modules installed:

And this is what my docker-compose.yml looks like. As you can see, I have defined the volumes for the modules in the n8n container as you have advised above.

version: "3"

services:
  traefik:
    image: "traefik"
    restart: always
    command:
      - "--api=true"
      - "--api.insecure=true"
      - "--providers.docker=true"
      - "--providers.docker.exposedbydefault=false"
      - "--entrypoints.websecure.address=:443"
      - "--certificatesresolvers.mytlschallenge.acme.tlschallenge=true"
      - "--certificatesresolvers.mytlschallenge.acme.email=${SSL_EMAIL}"
      - "--certificatesresolvers.mytlschallenge.acme.storage=/letsencrypt/acme.json"
    ports:
      - "443:443"
    volumes:
      - ${DATA_FOLDER}/letsencrypt:/letsencrypt
      - /var/run/docker.sock:/var/run/docker.sock:ro

  n8n:
    image: n8nio/n8n
    restart: always
    ports:
      - "127.0.0.1:5678:5678"
    labels:
      - traefik.enable=true
      - traefik.http.routers.n8n.rule=Host(`${SUBDOMAIN}.${DOMAIN_NAME}`)
      - traefik.http.routers.n8n.tls=true
      - traefik.http.routers.n8n.entrypoints=websecure
      - traefik.http.routers.n8n.tls.certresolver=mytlschallenge
      - traefik.http.middlewares.n8n.headers.SSLRedirect=true
      - traefik.http.middlewares.n8n.headers.STSSeconds=315360000
      - traefik.http.middlewares.n8n.headers.browserXSSFilter=true
      - traefik.http.middlewares.n8n.headers.contentTypeNosniff=true
      - traefik.http.middlewares.n8n.headers.forceSTSHeader=true
      - traefik.http.middlewares.n8n.headers.SSLHost=${DOMAIN_NAME}
      - traefik.http.middlewares.n8n.headers.STSIncludeSubdomains=true
      - traefik.http.middlewares.n8n.headers.STSPreload=true
    environment:
      - N8N_BASIC_AUTH_ACTIVE=true
      - N8N_BASIC_AUTH_USER
      - N8N_BASIC_AUTH_PASSWORD
      - N8N_HOST=${SUBDOMAIN}.${DOMAIN_NAME}
      - N8N_PORT=5678
      - N8N_PROTOCOL=https
      - NODE_ENV=production
      - WEBHOOK_TUNNEL_URL=https://${SUBDOMAIN}.${DOMAIN_NAME}/
      - NODE_FUNCTION_ALLOW_EXTERNAL=moment,sugar-date
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - ${DATA_FOLDER}/.n8n:/home/node/.n8n
      - /root/node_modules/sugar-core:/usr/local/lib/node_modules/sugar-core
      - /root/node_modules/sugar-date:/usr/local/lib/node_modules/sugar-date
      - /root/node_modules/moment:/usr/local/lib/node_modules/moment

and my .env

# Folder where data should be saved
DATA_FOLDER=/root/n8n/data/

# The top level domain to serve from
DOMAIN_NAME=domain.com

# The subdomain to serve from
SUBDOMAIN=sub

# DOMAIN_NAME and SUBDOMAIN combined decide where n8n will be reachable from
# above example would result in: https://sub.domain.com

# The user name to use for autentication - IMPORTANT ALWAYS CHANGE!
N8N_BASIC_AUTH_USER=user

# The password to use for autentication - IMPORTANT ALWAYS CHANGE!
N8N_BASIC_AUTH_PASSWORD=passredacted

# Optional timezone to set which gets used by Cron-Node by default
# If not set New York time will be used
GENERIC_TIMEZONE=American/Chicago

# The email address to use for the SSL certificate creation
[email protected]

# Allow external NPM modules
NODE_FUNCTION_ALLOW_EXTERNAL=moment,sugar-date

Thank you!

1 Like

Update: I figured it out. I am new to Docker and didn’t realize I had to rebuild the container after making changes to my docker-compose.yml. The following commands did the trick!

Thanks again for a fantastic product. It’s been a great learning experience for me getting it setup :slight_smile:

docker-compose up --force-recreate --build -d
docker image prune -f
1 Like

Ah great to hear that you found the problem and that you enjoy n8n.

Have fun!

Hi Jan, just wanted to thank you for that method, I’ve been banging my head against the wall trying to load gettest-parser without straying away of the official docker image and the way you wrote in the comment was the only thing that worked for me after hours of trying!
Thanks again :slight_smile:

3 Likes