Skip to content

SyntaxError: Cannot use import statement outside a module #11

Closed
@lvillacin

Description

@lvillacin

Wanted to open by thanking @maantje for this package. Really amazing and I love it.

However, recently I had some issues when it came to sending emails in an AWS EC2 Linux server. I would get this error:

SyntaxError: Cannot use import statement outside a module
    at internalCompileFunction (node:internal/vm:76:18)
    at wrapSafe (node:internal/modules/cjs/loader:1283:20)
    at Module._compile (node:internal/modules/cjs/loader:1328:27)
    at Module._extensions..js (node:internal/modules/cjs/loader:1422:10)
    at Module.load (node:internal/modules/cjs/loader:1203:32)
    at Module._load (node:internal/modules/cjs/loader:1019:12)
    at ModuleWrap.<anonymous> (node:internal/modules/esm/translators:203:29)
    at ModuleJob.run (node:internal/modules/esm/module_job:195:25)
    at async ModuleLoader.import (node:internal/modules/esm/loader:337:24)
    at async loadESM (node:internal/process/esm_loader:34:7)

Upon a lot of proding here are my findings:

  • Issue does not occur in my local MACOSX machine.
  • Error is thrown at /node_modules/.bin/tsx which is a separate package
  • If I SSH into the server, navigate to/node_modules/.bin, within the terminal, I can run the command that this package runs in Renderer.php to render the email with a few small tweaks: *absolute path to node* --import tsx *absolute path to render.tsx* *absolute path to email template* *data for email* (added --import)
    • With above, if I don't use --import, I get the same error
    • If I try to run the same (with --import) from the root project directory, it doesnt work
  • Since it seems that the issue lies with ES6 modules, I looked into the /node_modules/tsx folder itself (not the .bin export) and found that /dist/cli.mjs was able to run.
  • I was able to make the entire thing work from the root project directory by replacing the command like so *absolute path to node* *absolute path to /node_modules/tsx/dist/cli.mjs* *absolute path to render.tsx* *absolute path to email template* *data for email*
  • It seems that even with much effort, node does not try to run /node_modules/.bin/tsx as an ES6 module
    • "type":"module" in the package.json of my root application seems to be ignored by node
    • Flags like --experimental-modules and what not (i forgot what I tried to run) do not work
    • I honestly forgot what else I tried to run but it was a lot.

Fix:
I ended up writing my own Renderer.php by replacing the constructor as follows:

private function __construct(string $view, array $data = [])
{
  parent::__construct([
    $this->resolveNodeExecutable(),
    base_path('/node_modules/tsx/dist/cli.mjs'), // this is the change, referring to cli.mjs instead of tsx
    base_path('/vendor/maantje/react-email/render.tsx'),
    config('react-email.template_directory') . $view,
    json_encode($data)
  ], base_path());
}

I hope this can help others that may have encountered this issue. Currently, I am not sure if this is a persistent issue with Linux or what the root cause truly is and so I'm reluctant to create a PR that may not be useful to everyone.

I would love to hear your thoughts and discuss what the best next steps should be.

Some Context:

  • Server Env details:
    • PHP 8.2
    • Node 18.20
  • Others:
    • package.json of project has "type":"module"

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions