Skip to content

Marko 5 ESM Loading/Registering #1727

@adamchal

Description

@adamchal

Marko Version

5.15.1

Details

Trying to render a Marko template to HTML using Node in a module (ESM) context. Minimal repo showcasing the issue.

Using marko.load() to load the Marko template

import marko from "marko";
(async () => {
  const template = marko.load("./test.marko");
  const rendered = await template.render();
  console.log(rendered.getOutput());
})();

Expected Behavior

HTML output of test.marko logged to the console.

Actual Behavior

WARNING!!
Using `marko/compiler` has been deprecated, please upgrade to the `@marko/compiler` module.
  at node:internal/modules/cjs/loader:1095:14

/marko-5-esm-issue/components/foo.marko:1
div -- foo
       ^^^

SyntaxError: Unexpected identifier
    at Object.compileFunction (node:vm:352:18)
    at wrapSafe (node:internal/modules/cjs/loader:1025:15)
    at Module._compile (node:internal/modules/cjs/loader:1059:27)
    at Object.Module._extensions..js (node:internal/modules/cjs/loader:1124:10)
    at Module.load (node:internal/modules/cjs/loader:975:32)
    at Function.Module._load (node:internal/modules/cjs/loader:816:12)
    at Module.require (node:internal/modules/cjs/loader:999:19)
    at require (node:internal/modules/cjs/helpers:93:18)
    at Object.<anonymous> (/marko-5-esm-issue/test.marko:9:36)
    at Module._compile (node:internal/modules/cjs/loader:1095:14)

Possible Fix

However, if you marko.load the component before loading the template, it works.

import marko from "marko";
(async () => {
  marko.load("./components/foo.marko"); // now it works
  const template = marko.load("./test.marko");
  const rendered = await template.render();
  console.log(rendered.getOutput());
})();

But, since components can reference other components, you’d have to load them in order of least dependent to avoid the error.

I have not found clear documentation on how to do this in Marko 5. Previously, in Marko 4, I would require('marko/node-require').install() and then require the template. This isn’t working for me in Marko 5 in a CommonJS context.

But, I am only interested in the Node ESM output/context. markoc is able to compile the .marko templates without any issues, but the ESM output is not compatible with Node’s import requirements (no extensions to marko imports, etc.). I considered stringing Rollup or something else to transpile afterwards, but this started to feel like a lot of overkill for a template.

Additional Info

Your Environment

  • node.js 16.5.0
  • macOS 11.5.1

Steps to Reproduce

Clone and run the sample repo: https://github.com/adamchal/marko-5-esm-issue

Metadata

Metadata

Assignees

No one assigned

    Labels

    type:unverified bugA bug report that has not been verified

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions