node.js - 预呈现会导致 SyntaxError:无法在模块外使用 import 语句
问题描述
我正在尝试按此处所示prerender.ts
执行以预渲染我的 Angular 代码,但是当我尝试使用 执行它时,出现错误:ts-node prerender.ts
导入'zone.js/dist/zone-node';
^^^^^^SyntaxError: 不能
在 Module._compile (internal/modules/cjs/loader.js:892:18)的模块外使用 import 语句
从 NodeJS 执行此操作的正确方法是什么?这是prerender.ts
看起来的样子:
import 'zone.js/dist/zone-node';
import * as path from 'path';
import * as fs from 'fs';
import { enableProdMode } from '@angular/core';
import { renderModuleFactory } from '@angular/platform-server';
import { AppPrerenderModuleNgFactory } from './dist-prerender/main.bundle';
const distFolder = './dist';
const index = fs
.readFileSync(path.resolve(__dirname, `${distFolder}/index.html`), 'utf8')
.toString();
// we could automate this based on the app.routes.ts file but
// to keep it simple let's just create an array with the routes we want
// to prerender
const paths = [
'/about',
'/brews',
'/consultancy'];
enableProdMode();
// for every route render the html and save it in the correct folder
paths.forEach(p => renderToHtml(p, distFolder + p));
// don't forget to overwrite the index.html as well
renderToHtml('/index.html', distFolder);
function renderToHtml(url: string, folderPath: string): void {
// Render the module with the correct url just
// as the server would do
renderModuleFactory(AppPrerenderModuleNgFactory, {
url,
document: index
}).then(html => {
// create the route directory
if (url !== '/index.html') {
fs.mkdirSync(folderPath);
}
fs.writeFile(folderPath + '/index.html', html, (err => {
if (err) {
throw err;
}
console.log(`success`);
});
});
}
更新:我发现如果我tsc
以前先转译prerender.ts
为 JavaScript,然后用 node 执行它,我可以克服这个错误。但是,我开始收到一个错误,我认为这表明此代码未在 ngZone 的上下文中运行。所以代码仍然不正确。
解决方案
如此处所述:
当前的 node.js 稳定版本不支持 ES 模块。此外,ts-node 没有必要的钩子到 node.js 来支持 ES 模块。您需要在 tsconfig.json 中设置 "module": "commonjs" 以使代码正常工作。
因此,通过以下编译器选项:
ts-node --compiler-options '{"module": "commonjs"}' prerender.ts
当然,您可以只包含"module": "commonjs"
在您的(根)tsconfig.json 文件中的"compilerOptions"
. 这样你只需要执行:
ts-node prerender.ts