How to run a standalone cli script using a nextjs project?

Viewed 290

I have an working nextjs project.

I need to create a script that I can run from the CLI that uses some of the CRUD libraries I've written for the next project.

**/scripts/backup-assets.js **

import {getAllProjectsData} from '../lib/api/projects'

async function main() {
  const allProjectsData = await getAllProjectsData()
  console.info({allProjectsData})
}

main()

I'm getting this error:

$ node scripts/backup-assets.js 
(node:9736) Warning: To load an ES module, set "type": "module" in the package.json or use the .mjs extension.
(Use `node --trace-warnings ...` to show where the warning was created)
C:\Users\...\scripts\backup-assets.js:1
import {getAllProjectsData} from '../lib/api/projects'
^^^^^^

SyntaxError: Cannot use import statement outside a module
    at Object.compileFunction (node:vm:352:18)
    at wrapSafe (node:internal/modules/cjs/loader:1033:15)
    at Module._compile (node:internal/modules/cjs/loader:1069:27)
    at Object.Module._extensions..js (node:internal/modules/cjs/loader:1159:10)
    at Module.load (node:internal/modules/cjs/loader:981:32)
    at Function.Module._load (node:internal/modules/cjs/loader:822:12)
    at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:77:12)
    at node:internal/main/run_main_module:17:47
2 Answers

I haven't found a way to do this but here's a workaround:

  1. Create an API route called /api/scripts which takes a task param.

  2. Add a check to prevent it running in production (or authentication if you'd like to run your scripts in production context).

export default async function handler(req, res) {
  
  if (process.env.NODE_ENV === 'production') return res.status(404).end();

  switch (req.query.task) {
    case 'backup-assets':
      // code
    case 'migrate-database':
      // code

  1. Launch in dev or production mode as appropriate:
npm run dev
  1. Run the desired script from the command line with curl:
curl http://localhost:3000/api/scripts?task=backup-assets

or just visit that URL in the browser.

Here's how I managed to set up standalone deployment/maintenance scripts in my NextJS project.

First, install ts-node (CLI runner) and tsconfig-paths as local DEV dependencies. The last one is a ts-node plugin that loads path aliases from tsconfig.json. If you're using plain JavaScript or don't use path aliases, you can skip it.

npm i -D ts-node tsconfig-paths

Then add a script entry to your package.json:

...
"scripts": {
  ...
  "recreate-image-info": "ts-node -O '{\"module\": \"commonjs\"}' -r tsconfig-paths/register deploy/recreate-image-info.ts"
},

The -r flag with its parameter enables the tsconfig-paths plugin. The -O flag specifies compiler options.

Then, to run the script via CLI:

npm run recreate-image-info
Related