blinkk / amagaki

A high-performance TypeScript static website generator for building highly-interactive websites. Localization inbuilt. Flexible URLs. Content managed and templates separated.
https://amagaki.dev
MIT License
36 stars 2 forks source link

`amagaki build` is not compatible with `render()` from `@lit-labs/ssr` #218

Open alexboots opened 1 year ago

alexboots commented 1 year ago

I was writing a LitEnginePlugin using the same format as the PreactEnginePlugin (referencing this code) and when I import and try and use render from @lit-labs/ssr it breaks and shows this error.

import {render} from '@lit-labs/ssr';
           ^

Error [ERR_REQUIRE_ESM]: require() of ES Module /Users/me/amagaki-lit/node_modules/@lit-labs/ssr/index.js from /Users/me/amagaki-lit/plugins/lit-engine.ts not supported.
Instead change the require of index.js in /Users/me/amagaki-lit/plugins/lit-engine.ts to a dynamic import() which is available in all CommonJS modules.
    at Object.<anonymous> (/Users/me/amagaki-lit/plugins/lit-engine.ts:4:12)

This happens specifically during the amagaki build step, the gulp build completes successfully.

Example of the lit-engine.ts code I wrote below - which is basically the same as the preact-engine.ts code:

Note: if I comment out import {render} from '@lit-labs/ssr'; everything works as expected - I see "Footer" show up in the final /build HTML where the footer partial is used in the templates, and "Spacer" for spacer - but when I import {render} from '@lit-labs/ssr'; amagaki build shows the above error.

Second note: I'm logging render like console.log(render) just so typescript pulls in '@lit-labs/ssr';`, otherwise typescript will ignore the import). Everthing besides the {render} import and logging that out is basically the exact same as the preact-engine file.

import {PluginComponent, Pod, TemplateEngineComponent} from '@amagaki/amagaki';
import {register as esbuildRegister} from 'esbuild-register/dist/node';

import {render} from '@lit-labs/ssr';

export class LitEnginePlugin implements PluginComponent {
  config: Record<string, any>;
  pod: Pod;

  constructor(pod: Pod, config: Record<string, any>) {
    this.pod = pod;
    this.config = config;
    this.pod.engines.associate('.ts', LitEngine);
  }

  static register(pod: Pod, config?: any) {
    esbuildRegister();
    pod.plugins.register(LitEnginePlugin, config ?? {});
  }

  createTemplateEngineHook(templateEngine: TemplateEngineComponent, extension: string) {  }
}

class LitEngine implements TemplateEngineComponent {
  pod: Pod;

  constructor(pod: Pod) {
    this.pod = pod;
  }

  async render(path: string, context: any): Promise<string> {
    const modulePath = this.pod.getAbsoluteFilePath(path);
    // Facilitate autoreload on dev.
    if (this.pod.env.dev) {
      delete require.cache[require.resolve(modulePath)];
    }
    const createElement = require(modulePath);
    let vDom;

    console.log('render', render);

    if(modulePath.includes('Footer.ts')) {
      vDom = "Footer";
    }

    if(modulePath.includes('Spacer.ts')) {
      vDom = "Spacer";
    }

    return vDom
  }

  async renderFromString(template: string, context: any): Promise<string> {
    throw new Error('renderToString is not implemented.');
  }
}

I poked around the 11ty lit plugin code to see why a simiilar issue isn't happening there and noticed this: https://github.com/lit/lit/blob/main/packages/labs/eleventy-plugin-lit/src/index.ts#L143

I stopped digging here and figured I would open an issue, but I'd love to build out a version of amagaki leaning on lit-html and their ssr/hydration stuff!