Friday 5 March 2021

Why does a dynamically imported ESModule return JSON, when the module exports only plaintext?

I am reasonably familiar with ES2015 Modules, but, right now, I am (simultaneously) getting my head around:

  • Heroku
  • Deno
  • Oak
  • TypeScript

I'm sure I've missed something elementary here, but I cannot find it.

I have two versions of a template, which look like this:

template-static.ts

import page from './page.ts';

let template = page;  // Normally, the template will add a lot more to page

export default template;

template-dynamic.ts

const page = await import('./page.ts');

let template = page;  // Normally, the template will add a lot more to page

export default template;

In this test setup, each template (whether using static or dynamic import) imports the same module:

page.ts

let page = `

  <h1>Test Page</h1>
  <p>This is the <strong>Test Page</strong>.</p>
  <ul>
    <li>Go to the <a href="/test-page-static-import/">Test Page (static import)</a> Page</li>
    <li>Go to the <a href="/test-page-dynamic-import/">Test Page (dynamic import)</a> Page</li>
  </ul>
`;

export default page;

Finally, I have the following HTTP Server (using Oak):

server.ts

import { Application, Router } from 'https://deno.land/x/oak/mod.ts';
import * as flags from 'https://deno.land/std/flags/mod.ts';

import templateStatic from './template-static.ts';
import templateDynamic from './template-dynamic.ts';

const {args} = Deno;
const DEFAULT_PORT = 8080;
const argPort = flags.parse(args).port;
const port = argPort ? Number(argPort) : DEFAULT_PORT;

const app = new Application();
const router = new Router();

app.use(router.routes());
app.use(router.allowedMethods());


router.get('/test-page-static-import', ({ response }: { response: any }) => {
    response.status = 200;
    response.headers.set('Content-Type', 'text/html');
    response.body = templateStatic;
});


router.get('/test-page-dynamic-import', ({ response }: { response: any }) => {
    response.status = 200;
    response.headers.set('Content-Type', 'text/html');
    response.body = templateDynamic;
});

console.log(`Server is running on port ${port}`)

await app.listen({ port });

When I deploy the app to Heroku it works, but with the following outputs:

/test-page-static-import

  <h1>Test Page</h1>
  <p>This is the <strong>Test Page</strong>.</p>
  <ul>
    <li>Go to the <a href="/test-page-static-import/">Test Page (static import)</a> Page</li>
    <li>Go to the <a href="/test-page-dynamic-import/">Test Page (dynamic import)</a> Page</li>
  </ul>

/test-page-dynamic-import

{"default":"\n\n  <h1>Test Page</h1>\n  <p>This is the <strong>Test Page</strong>.</p>\n  <ul>\n    <li>Go to the <a href=\"/test-page-static-import/\">Test Page (static import)</a> Page</li>\n    <li>Go to the <a href=\"/test-page-dynamic-import/\">Test Page (dynamic import)</a> Page</li>\n  </ul>\n"}

It's clear to me that the template which uses static import is importing plaintext and serving it as text/html while the template which uses dynamic import is importing JSON and serving it as text/html.

Why is the dynamic import() returning JSON?



from Why does a dynamically imported ESModule return JSON, when the module exports only plaintext?

No comments:

Post a Comment