Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

nodejs_compat is not working on Cloudflare Pages

I deploy Remix to Cloudflare Pages with Remix official Cloudflare template.

All went well until I added jsonwebtoken package. It shows Could not resolve "crypto" as well as "stream".

This is the reproduction: https://github.com/gjc14/cannot-resolve-native-package-on-remix-cloudflare


I've added nodejs_compat on both wrangler.toml and Dashboard, and I could not add prfix node: cause these are used in the package. Does anyone has experience for fixing this issue?

Also tried NODE_VERSION setting in Cloudflare, but not working.

00:48:56.191    Detected the following tools from environment: [email protected], [email protected]
00:48:56.192    Installing nodejs 20.5.1
00:48:56.266    nodejs 20.5.1 is already installed
...
00:49:31.771    ✘ [ERROR] 6 error(s) and 0 warning(s) when compiling Worker.
00:49:31.772    
00:49:31.772    
00:49:31.775    
00:49:31.777    ✘ [ERROR] Could not resolve "crypto"
00:49:31.777    
00:49:31.777        ../node_modules/jsonwebtoken/sign.js:12:65:
00:49:31.777          12 │ ...KeyObject, createSecretKey, createPrivateKey } = require('crypto')
00:49:31.777             ╵                                                             ~~~~~~~~
00:49:31.777    
00:49:31.777      The package "crypto" wasn't found on the file system but is built into node.
00:49:31.777      Add the "nodejs_compat" compatibility flag to your Pages project and make sure to prefix the module name with "node:" to enable Node.js compatibility.
✘ [ERROR] Could not resolve "crypto"
23:55:39.338    
23:55:39.338        ../node_modules/jsonwebtoken/sign.js:12:65:
23:55:39.338          12 │ ...KeyObject, createSecretKey, createPrivateKey } = require('crypto')
23:55:39.338             ╵                                                             ~~~~~~~~
23:55:39.339    
23:55:39.339      The package "crypto" wasn't found on the file system but is built into node.
23:55:39.339      Add the "nodejs_compat" compatibility flag to your Pages project and make sure to prefix the module name with "node:" to enable Node.js compatibility.
// package.json
{
    "name": "name",
    "private": true,
    "sideEffects": false,
    "type": "module",
    "scripts": {
        "build": "remix vite:build",
        "deploy": "wrangler pages deploy ./build/client",
        "dev": "remix vite:dev",
        "lint": "eslint --ignore-path .gitignore --cache --cache-location ./node_modules/.cache/eslint .",
        "start": "wrangler pages dev ./build/client",
        "typecheck": "tsc",
        "typegen": "wrangler types"
    },
    "dependencies": {
        "@radix-ui/react-dialog": "^1.1.1",
        "@radix-ui/react-label": "^2.1.0",
        "@radix-ui/react-slot": "^1.1.0",
        "@remix-run/cloudflare": "^2.11.2",
        "@remix-run/cloudflare-pages": "^2.11.2",
        "@remix-run/react": "^2.11.2",
        "class-variance-authority": "^0.7.0",
        "clsx": "^2.1.1",
        "framer-motion": "^11.3.30",
        "isbot": "^4.1.0",
        "jsonwebtoken": "^9.0.2",
        "lucide-react": "^0.435.0",
        "react": "^18.2.0",
        "react-dom": "^18.2.0",
        "tailwind-merge": "^2.5.2",
        "tailwindcss-animate": "^1.0.7"
    },
    "devDependencies": {
        "@cloudflare/workers-types": "^4.20240512.0",
        "@remix-run/dev": "^2.11.2",
        "@tailwindcss/typography": "^0.5.14",
        "@types/jsonwebtoken": "^9.0.6",
        "@types/react": "^18.2.20",
        "@types/react-dom": "^18.2.7",
        "@typescript-eslint/eslint-plugin": "^6.7.4",
        "@typescript-eslint/parser": "^6.7.4",
        "autoprefixer": "^10.4.19",
        "eslint": "^8.38.0",
        "eslint-import-resolver-typescript": "^3.6.1",
        "eslint-plugin-import": "^2.28.1",
        "eslint-plugin-jsx-a11y": "^6.7.1",
        "eslint-plugin-react": "^7.33.2",
        "eslint-plugin-react-hooks": "^4.6.0",
        "postcss": "^8.4.38",
        "tailwindcss": "^3.4.4",
        "typescript": "^5.1.6",
        "vite": "^5.1.0",
        "vite-tsconfig-paths": "^4.2.1",
        "wrangler": "3.57.1"
    },
    "engines": {
        "node": ">=20.0.0"
    }
}
# wrangler.toml
compatibility_flags = ["nodejs_compat"]

[[services]]
binding = "DB"    # name of the binding in `env`
service = "another-worker"    # name of the worker in the dashboard

enter image description here

The way I import jsonwebtoken:

// auth.ts
import jwt from 'jsonwebtoken'
like image 518
Gabriel JC Avatar asked Aug 31 '25 20:08

Gabriel JC


1 Answers

My problem was, I was importing dependency from "@remix-run/node", instead of "@remix-run/cloudflare":

- import type { ActionFunction } from "@remix-run/node";
- import { json } from "@remix-run/node";
+ import { ActionFunction, json } from "@remix-run/cloudflare";
like image 56
kasi Avatar answered Sep 05 '25 01:09

kasi