首页 > 解决方案 > 预呈现会导致 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.jsangulartypescriptmodule

解决方案


如此处所述:

当前的 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


推荐阅读