我试图以seen here的身份执行prerender.ts
来渲染我的Angular代码,但是当我尝试使用 ts-node prerender.ts
执行它时,我得到了错误:
导入'zone.js / dist / zone-node';
^^^^^^SyntaxError:无法在模块外部使用import语句
在Module._compile(internal / modules / cjs / loader.js:892:18)
从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上下文中运行。因此代码仍然不正确。
答案 0 :(得分:0)
如here所述:
当前的node.js稳定版本不支持ES模块。另外,ts-node没有进入node.js所需要的钩子来支持ES模块。您需要在tsconfig.json中设置“ module”:“ commonjs”才能使代码正常工作。
因此,通过下面的编译器选项:
ts-node --compiler-options '{"module": "commonjs"}' prerender.ts
当然,您可以仅将"module": "commonjs"
包含在"compilerOptions"
下的(根)tsconfig.json文件中。这样,您只需要执行:
ts-node prerender.ts