使用Angular4 + Universal + ng-bootstrap时出现了“Unexpected token import”错误

9
所以,我升级到angular 4+,只是为了利用通用包进行服务器端渲染来实现SEO目的。我通过将现有的angular 2+项目升级到angular 4+并从https://github.com/evertonrobertoauler/cli-universal-demo/commit/a2610286bd3db5d4f4cce4318d7c220c11963eb6进行所有必要的配置来实现这一点。
只有一个区别,我使用的是ng-bootstraphttps://ng-bootstrap.github.io/#/home(v1.0.0-alpha.22)。但是当我使用npm run start-u-dev运行节点服务器时,在ng-bootstrap中的import关键字中出现了错误。
app-ui@0.0.0 start-u-dev /Users/giric/Projects/apnaDoctor/webapp/appUI  
ts-node src/server.ts  

/appUI/node_modules/@ng-bootstrap/ng-bootstrap/accordion/accordion.module.js:1
(function (exports, require, module, __filename, __dirname) { import { NgModule } from '@angular/core';  
                                                              ^^^^^^  
SyntaxError: Unexpected token import  
    at createScript (vm.js:53:10)  
    at Object.runInThisContext (vm.js:95:10)  
    at Module._compile (module.js:543:28)  
    at Object.Module._extensions..js (module.js:580:10)  
    at Module.load (module.js:488:32)  
    at tryModuleLoad (module.js:447:12)  
    at Function.Module._load (module.js:439:3)  
    at Module.require (module.js:498:17)  
    at require (internal/module.js:20:19)  
    at Object.<anonymous> (/appUI/dist/ngfactory/src/app/app.server.module.ngfa
ctory.ts:18:1)  
    at Module._compile (module.js:571:32)  
    at Module.m._compile (/appUI/node_modules/ts-node/src/index.ts:406:23)  
    at Module._extensions..js (module.js:580:10)  
    at Object.require.extensions.(anonymous function) [as .ts]
(/webapp/appUI/node_mod
ules/ts-node/src/index.ts:409:12)  
    at Module.load (module.js:488:32)  

pm ERR! Darwin 16.6.0  
npm ERR! argv "/usr/local/bin/node" "/usr/local/bin/npm" "run" "start-u-dev"  
npm ERR! node v7.7.4  
npm ERR! npm  v4.1.2  
npm ERR! code ELIFECYCLE  
npm ERR! app-ui@0.0.0 start-u-dev: `ts-node src/server.ts`  
npm ERR! Exit status 1  
npm ERR!  
npm ERR! Failed at the app-ui@0.0.0 start-u-dev script 'ts-node src/server.ts'.  
npm ERR! Make sure you have the latest version of node.js and npm installed.  
npm ERR! If you do, this is most likely a problem with the app-ui package,  
npm ERR! not with npm itself.  
npm ERR! Tell the author that this fails on your system:  
npm ERR!     ts-node src/server.ts  
npm ERR! You can get information on how to open an issue for this project with:  
npm ERR!     npm bugs app-ui  
npm ERR! Or if that isn't available, you can get their info via:  
npm ERR!     npm owner ls app-ui  
npm ERR! There is likely additional logging output above.  

npm ERR! Please include the following file with any support request:  

这是我的 package.json 文件内容:
{  
  "name": "app-ui",  
  "version": "0.0.0",  
  "license": "MIT",  
  "scripts": {  
    "ng": "ng",  
    "start": "ng serve",  
    "build": "ng build",  
    "test": "ng test",
    "lint": "ng lint",
    "e2e": "ng e2e",
    "prestart": "npm install",
    "postinstall": "bower install",
    "prestart-u-dev": "npm install && ng build && ngc",
    "start-u-dev": "ts-node src/server.ts",
    "prestart-u-prod": "npm install && ng build --prod && ngc",
    "start-u-prod": "ts-node src/server.ts"
  },
  "private": true,
  "dependencies": {
    "@angular/animations": "^4.0.1",
    "@angular/cli": "^1.0.0-rc.1",
    "@angular/common": "^4.0.1",
    "@angular/compiler": "^4.0.1",
    "@angular/compiler-cli": "^4.0.1",
    "@angular/core": "^4.0.1",
    "@angular/forms": "^4.0.1",
    "@angular/http": "^4.0.1",
    "@angular/platform-browser": "^4.0.1",
    "@angular/platform-browser-dynamic": "^4.0.1",
    "@angular/platform-server": "^4.0.1",
    "@angular/router": "^4.0.1",
    "@ng-bootstrap/ng-bootstrap": "^1.0.0-alpha.22",
    "angular2-toaster": "^3.0.1",
    "core-js": "^2.4.1",
    "ng2-webstorage": "^1.5.1",
    "rxjs": "^5.1.0",
    "rxjs-es": "^5.0.0-beta.12",
    "typescript": "^2.2.2",
    "ui-router-ng2": "^1.0.0-beta.4",
    "zone.js": "^0.7.6"
  },
  "devDependencies": {
    "@types/jasmine": "2.5.38",
    "@types/node": "~6.0.60",
    "codelyzer": "~2.0.0",
    "jasmine-core": "~2.5.2",
    "jasmine-spec-reporter": "~3.2.0",
    "karma": "~1.4.1",
    "karma-chrome-launcher": "~2.0.0",
    "karma-cli": "~1.0.1",
    "karma-coverage-istanbul-reporter": "^0.2.0",
    "karma-jasmine": "~1.1.0",
    "karma-jasmine-html-reporter": "^0.2.2",
    "node-sass": "^4.5.0",
    "protractor": "~5.1.0",
    "raw-loader": "^0.5.1",
    "sass-loader": "^6.0.3",
    "ts-node": "~2.0.0",
    "tslint": "~4.4.2"
  }
}

更新: 我先前删除了angular2-toaster,但是为了确保不只是toaster模块引起了相同的错误,我又将其添加回来。结果发现,angular2-toaster和ng-bootstrap都引发了相同的错误。

更新2: 当我使用ng server运行服务器时,它可以正常工作,使用angular 4+与ng-bootstrap和angular2-toaster没有问题。

有什么建议吗?提前感谢。


你能移除ng-bootstrap吗? - Roman C
可以这样做,而且肯定有效,但这是最后的选择,需要剥离 both toaster 和 ng-bootstrap,并使用它们组件的自定义实现。我想保留它们,因为我已经在使用它们。 - ggoyal
1
@ggoyal,你解决了这个问题吗?我也遇到了同样的问题。 - Praveen Rana
@PraveenRana:试试这个。https://github.com/evertonrobertoauler/cli-universal-demo/issues/4 - ggoyal
3个回答

7

对于那些试图了解解决方案的人,你基本上需要使用和白名单angular2-toaster和其他相关模块。

  1. if using angular-cli, use ng eject to create a webpack.config.js
  2. install the webpack-node-externals dependency via npm install and add the following lines in the webpack.config.js file

    const nodeExternals = require('webpack-node-externals');
    
    module.exports = {
      ...
      target: 'node',
      externals: [nodeExternals({
        whitelist: [
          /^@ng-bootstrap\/ng-bootstrap/,
          /^angular2\-toaster/,
        ]
      })],
      ...
    }
    

1
我的package.json的start是否仍然应该像这样:"start": "ngc && ts-node src/server.ts"?我使用与上面完全相同的代码(没有toaster),但似乎仍然遇到了问题:( - Jamie Street

0

显然这是一个构建问题 - 你的服务器端代码似乎没有正确的转译设置。请注意,ng-bootstrap(像其他任何Angular 2.x+库一样!)以以下方式发布代码:

  • 未捆绑的ES2015代码(带有导入)
  • UMD捆绑的ES5代码(不带导入)

如果您想在服务器上运行ng-bootstrap,则有两个选择:要么设置适当的转译管道并使用未捆绑的代码或者从包中导入(位于bundles文件夹中)。

如果您决定采用ES5捆绑方法,则应从@ng-bootstrap/ng-bootstrap/dist/ng-bootstrap导入,而不仅仅是@ng-bootstrap/ng-bootstrap)。但是,为了明确起见,我不建议这样做,因为您将不得不在服务器端和客户端代码中使用不同的导入。


看起来你对构建问题的评论是正确的,但请注意,任何遵循官方ng-cli[指南][1]的ng-bootstrap用户都会遇到相同的问题。目前我还不清楚如何解决这个问题,但有可能你们希望在手册的安装部分中包含一些相关内容。 [1]: https://github.com/angular/angular-cli/wiki/stories-universal-rendering - ŁukaszBachman

-1

我认为你可以创建两个模块。一个是用于浏览器的,导入了ng-bootstrap,另一个是用于服务器的,没有导入ng-bootstrap。我认为你需要再创建一个共享组件和服务的通用模块,用于浏览器模块和服务器模块之间的共享。模态框不会被服务器渲染到SEO中。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接