为什么动态导入的 ESModule return JSON,当模块仅导出纯文本时?
Why does a dynamically imported ESModule return JSON, when the module exports only plaintext?
我相当熟悉 ES2015 Modules
,但是,现在,我(同时)开始思考:
Heroku
Deno
Oak
TypeScript
我确定我在这里遗漏了一些基本知识,但我找不到它。
我有两个版本的模板,如下所示:
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;
在此测试设置中,每个模板(无论是使用静态导入还是动态导入)都导入相同的模块:
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;
最后,我有以下 HTTP 服务器(使用 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 });
当我将应用程序部署到 Heroku 时,它可以运行,但输出如下:
/测试页面静态导入
<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>
/测试页面动态导入
{"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"}
我很清楚,使用 static import 的模板正在导入 plaintext
并将其作为 text/html
使用,而使用 [=62] 的模板=]dynamic import 正在导入 JSON
并将其用作 text/html
。
为什么动态 import()
返回 JSON?
原因是动态导入的 return 值不是您期望的默认导入,而是围绕它的对象包装器。
注意dynamic import webpack documentation上的例子。
return import('lodash')
.then(({ default: _ }) => {
const element = document.createElement('div');
element.innerHTML = _.join(['Hello', 'webpack'], ' ');
如果您想从动态导入的文件访问默认导入,您必须通过 resolvedPromise.default
访问它。
在您的情况下,您可以从 page.ts
访问默认导入,如下所示:
const { default: page } = await import('./page.ts');
let template = page;
export default template;
我相当熟悉 ES2015 Modules
,但是,现在,我(同时)开始思考:
Heroku
Deno
Oak
TypeScript
我确定我在这里遗漏了一些基本知识,但我找不到它。
我有两个版本的模板,如下所示:
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;
在此测试设置中,每个模板(无论是使用静态导入还是动态导入)都导入相同的模块:
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;
最后,我有以下 HTTP 服务器(使用 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 });
当我将应用程序部署到 Heroku 时,它可以运行,但输出如下:
/测试页面静态导入
<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>
/测试页面动态导入
{"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"}
我很清楚,使用 static import 的模板正在导入 plaintext
并将其作为 text/html
使用,而使用 [=62] 的模板=]dynamic import 正在导入 JSON
并将其用作 text/html
。
为什么动态 import()
返回 JSON?
原因是动态导入的 return 值不是您期望的默认导入,而是围绕它的对象包装器。
注意dynamic import webpack documentation上的例子。
return import('lodash')
.then(({ default: _ }) => {
const element = document.createElement('div');
element.innerHTML = _.join(['Hello', 'webpack'], ' ');
如果您想从动态导入的文件访问默认导入,您必须通过 resolvedPromise.default
访问它。
在您的情况下,您可以从 page.ts
访问默认导入,如下所示:
const { default: page } = await import('./page.ts');
let template = page;
export default template;