预渲染会导致SyntaxError:无法在模块外部使用import语句

时间:2019-11-12 20:24:20

标签: node.js angular typescript module

我试图以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上下文中运行。因此代码仍然不正确。

1 个答案:

答案 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