如何在Next.js项目中运行独立的CLI脚本?

11

我有一个正在运行的Next.js项目。

我需要创建一个脚本,可以从CLI中运行,并使用我为next项目编写的一些CRUD库。

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

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

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

main()

我遇到了这个错误:

$ 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

你尝试过警告信息中建议的方法吗?_"警告:要加载ES模块,请在package.json中设置"type":"module"或使用.mjs扩展名。"_ 请参见SyntaxError: Cannot use import statement outside a module - juliomalves
我猜如果你在使用js,你可以直接将模块作为模块执行;但是如果你使用TS或特殊的nextjs导入,例如css,那么它就需要被编译。@user2632759,你解决了这个问题吗? - Richard Scarrott
3个回答

17
使用 TSX。它可以立即在 NextJS 中使用,支持 JavaScript 和 TypeScript 两种语言。

安装:

npm install --save-dev tsx

声明你的脚本。在package.json中:

...
"scripts": {
  ...
  "my-js-script": "tsx scripts/my-script.js",
  "my-ts-script": "tsx scripts/my-script.ts"
},

运行它:

npm run my-js-script
npm run my-ts-script

您先生,您真是个救星!谢谢! 我正在使用纯JS开发一个Next.js应用程序,其中使用了Prisma(是的,我知道,不使用TS真是个罪过——这是一个个人项目,我需要快速推进,而类型转换实在太麻烦了)。我为应用程序开发了一堆辅助函数,然后我还需要在我的Prisma seed.js文件中使用它们,但就是不起作用!我找到的所有解决方法要么使用了TS特定的CLI选项,要么说要在package.json中添加"type": "module",但这只会引发不同的错误,而且导致应用程序本身停止工作! - undefined

2
我还没有找到一种方法来做到这一点,但是这里有一个解决方法:
1. 创建一个名为/api/scripts的API路由,它需要一个任务参数。 2. 添加检查以防止在生产环境中运行(或者如果您希望在生产上下文中运行脚本,则需要身份验证)。
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. 根据需要在开发模式或生产模式下启动:
npm run dev
  1. 使用curl从命令行运行所需的脚本:
curl http://localhost:3000/api/scripts?task=backup-assets

或者只需在浏览器中访问该URL。

1
这是我如何在我的NextJS项目中设置独立的部署/维护脚本的方法。
首先,安装本地开发依赖项ts-node(CLI运行程序)和tsconfig-paths。后者是一个ts-node插件,从tsconfig.json中加载路径别名。如果您使用普通JavaScript或不使用路径别名,则可以跳过它。
npm i -D ts-node tsconfig-paths

然后在你的package.json文件中添加一个脚本条目:

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

使用 -r 标志及其参数启用 tsconfig-paths 插件。使用 -O 标志指定编译器选项。
然后,通过CLI运行脚本:
npm run recreate-image-info

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接