Move NPM packages from old NR installation to fresh NR

I had the problem to move over all existing packages from my existing Node Red installation to another so I created a python script which may be useful for similar cases. (Maybe there are better solutions, if so let me know):

Arguments:
0: file path to package.json
1: file / name / path where to put the output (shell install script)
2: optional to remove the version string and replace with latest: --noversion

Python3:

import json
import argparse

def extract_packages(package_json_path):
    with open(package_json_path, 'r') as f:
        package_data = json.load(f)
    dependencies = package_data.get('dependencies', {})
    dev_dependencies = package_data.get('devDependencies', {})
    packages = dict(**dependencies, **dev_dependencies)
    return packages

def generate_shell_script(package_json_path, output_script_path, use_latest_version):
    packages = extract_packages(package_json_path)
    with open(output_script_path, 'w') as f:
        f.write('#!/bin/bash\n')
        f.write('npm install \\\n')
        for package_name, package_version in packages.items():
            if use_latest_version:
                f.write('\t{}@latest \\\n'.format(package_name))
            else:
                f.write('\t{}@{} \\\n'.format(package_name, package_version))
        f.write('\n')
    print('Shell script generated: {}'.format(output_script_path))

if __name__ == '__main__':
    parser = argparse.ArgumentParser(description='Generate a shell script to install Node.js packages from a package.json file')
    parser.add_argument('package_json_path', help='Path to the package.json file')
    parser.add_argument('output_script_path', help='Path to the output shell script file')
    parser.add_argument('--noversion', action='store_true', help='Install the latest version of the packages')
    args = parser.parse_args()
    generate_shell_script(args.package_json_path, args.output_script_path, args.noversion)

usage example:

pi@raspberrypi3A:~/PackageExtractor $ python3 extract.py package.json ../.node-red/gogo.sh --noversion

source package.json:

{
    "name": "node-red-project",
    "description": "A Node-RED Project",
    "version": "0.0.1",
    "private": true,
    "dependencies": {
        "@kuehnelbs/node-red-contrib-nextcloud": "~0.1.3",
        "node-red-contrib-arp": "0.0.2",
        "node-red-contrib-chartjs": "~0.4.1",
        "node-red-contrib-dashboard-bar-chart-data": "~0.9.5",
        "node-red-contrib-filebrowser": "0.0.25",
        "node-red-contrib-fs-ops": "~1.5.0",
        "node-red-contrib-ftp-server": "~0.3.0",
        "node-red-contrib-gc-trigger": "0.0.1",
        "node-red-contrib-google-tts": "~1.1.1",
        "node-red-contrib-grok": "0.0.2",
        "node-red-contrib-http-logger": "~2.0.1",
        "node-red-contrib-ifttt-broker": "~0.2.4",
        "node-red-contrib-json": "~0.2.0",
        "node-red-contrib-mdashboard": "~0.1.17",
        "node-red-contrib-media-tags": "0.0.6",
        "node-red-contrib-merge-topic": "~0.1.2",
        "node-red-contrib-micropi": "~1.0.5",
        "node-red-contrib-os": "~0.1.7",
        "node-red-contrib-persist": "~1.0.3",
        "node-red-contrib-pi-omxplayer": "~1.0.1",
        "node-red-contrib-pixelit": "~0.2.9",
        "node-red-contrib-play-audio-file": "0.0.1",
        "node-red-contrib-play-sound": "~0.2.0",
        "node-red-contrib-python3-function": "0.0.4",
        "node-red-contrib-pythonshell": "~1.5.4",
        "node-red-contrib-rsync": "~1.1.1",
        "node-red-contrib-sendkeys": "0.0.1",
        "node-red-contrib-smartswitch": "0.0.1",
        "node-red-contrib-sunpos": "~1.4.1",
        "node-red-contrib-tankerkoenig": "0.0.3",
        "node-red-contrib-thingspeak": "0.0.4",
        "node-red-contrib-ui-level": "~0.1.2",
        "node-red-contrib-ui-media": "~1.1.4",
        "node-red-contrib-wav": "~1.0.0",
        "node-red-contrib-wavenet": "~2.5.0",
        "node-red-dashboard": "~2.17.1",
        "node-red-node-daemon": "0.0.25",
        "node-red-node-pi-gpiod": "0.0.13",
        "node-red-node-random": "~0.1.3",
        "node-red-node-ui-table": "~0.1.5",
        "node-red-node-watson": "~0.7.8"
    }
}

output shell script:

#!/bin/bash
npm install \
	@kuehnelbs/node-red-contrib-nextcloud@latest \
	node-red-contrib-arp@latest \
	node-red-contrib-chartjs@latest \
	node-red-contrib-dashboard-bar-chart-data@latest \
	node-red-contrib-filebrowser@latest \
	node-red-contrib-fs-ops@latest \
	node-red-contrib-ftp-server@latest \
	node-red-contrib-gc-trigger@latest \
	node-red-contrib-google-tts@latest \
	node-red-contrib-grok@latest \
	node-red-contrib-http-logger@latest \
	node-red-contrib-ifttt-broker@latest \
	node-red-contrib-json@latest \
	node-red-contrib-mdashboard@latest \
	node-red-contrib-media-tags@latest \
	node-red-contrib-merge-topic@latest \
	node-red-contrib-micropi@latest \
	node-red-contrib-os@latest \
	node-red-contrib-persist@latest \
	node-red-contrib-pi-omxplayer@latest \
	node-red-contrib-pixelit@latest \
	node-red-contrib-play-audio-file@latest \
	node-red-contrib-play-sound@latest \
	node-red-contrib-python3-function@latest \
	node-red-contrib-pythonshell@latest \
	node-red-contrib-rsync@latest \
	node-red-contrib-sendkeys@latest \
	node-red-contrib-smartswitch@latest \
	node-red-contrib-sunpos@latest \
	node-red-contrib-tankerkoenig@latest \
	node-red-contrib-thingspeak@latest \
	node-red-contrib-ui-level@latest \
	node-red-contrib-ui-media@latest \
	node-red-contrib-wav@latest \
	node-red-contrib-wavenet@latest \
	node-red-dashboard@latest \
	node-red-node-daemon@latest \
	node-red-node-pi-gpiod@latest \
	node-red-node-random@latest \
	node-red-node-ui-table@latest \
	node-red-node-watson@latest \

Let me know if there are better ways or things I missed.

I think a better way is

cd ~/.node-red
npm install

Provided you have copied over package.json and package-lock.json that will install the same versions as on the original system. If you delete package-lock.json then it will install the latest versions.

1 Like

Thx @Colin I will try that :slight_smile:

Agree with Colin. This is one of the strengths of Node.js based applications. All you need to do is copy over the package.json.