9

So I upgraded to angular 4+ just so that I can leverage the universal package for server side rendering for SEO purposes. I implemented that in my existing angular 2+ project by upgrading it to angular 4+ and did all the necessary configuration from https://github.com/evertonrobertoauler/cli-universal-demo/commit/a2610286bd3db5d4f4cce4318d7c220c11963eb6.

There is only one difference I am using ng-bootstrap https://ng-bootstrap.github.io/#/home (v1.0.0-alpha.22). But when I run the node server using npm run start-u-dev I get this error for import keyword in ng-bootstrap.


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:  

This is what my package.json looks like

{  
  "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"
  }
}

Update: Earlier i removed angular2-toaster, but then i added it again just to make sure it wasn't just toaster module that is throwing the same error. Turns out, both angular2-toaster and ng-bootstrap threw the same error.

Update 2: When I run the server using ng server, it works fine, no issues with using ng-bootstrap and angular2-toaster with angular 4+

Any suggestions? Thanks in advance.

ggoyal
  • 150
  • 1
  • 6
  • Can you remove ng-bootstrap? – Roman C Apr 02 '17 at 13:37
  • Yes that can and it definitely works, but that is the last option by stripping down both toaster and ng-bootstrap and using custom implementations for their components. I want to keep them since I am already using them. – ggoyal Apr 02 '17 at 14:55
  • 1
    @ggoyal have you resolved this problem ? I am facing the same issue – Praveen Rana Apr 27 '17 at 16:57
  • @PraveenRana: Try this. https://github.com/evertonrobertoauler/cli-universal-demo/issues/4 – ggoyal May 01 '17 at 04:07

3 Answers3

7

For those trying to understand what the solution is, you basically want to use and whitelist angular2-toaster and other modules giving this issue.

  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/,
        ]
      })],
      ...
    }
    
Gianfranco P.
  • 10,049
  • 6
  • 51
  • 68
Ahmed-Anas
  • 5,471
  • 9
  • 50
  • 72
  • 1
    Should my package.json `start` still look like; `"start": "ngc && ts-node src/server.ts"` I have the exact same code as above (without toaster) and still seem to be running into issues :( – Jamie Street Sep 14 '17 at 15:33
0

It is clearly a build issue - you don't seem to have a proper transpilation setup for your server-side code. Please note that ng-bootstrap (as any other Angular 2.x+ library!) is shipping code in the following manner:

  • unbundled ES2015 code (with imports)
  • UMD-bundled ES5 code (without imports)

If you want to run ng-bootstrap on the server you've got 2 choices: either setup proper transpilation pipeline and used unbundled code or import from a bundle (located in bundles folder).

If you decide to go with a ES5 bundle approach you should be importing from @ng-bootstrap/ng-bootstrap/dist/ng-bootstrap instead of just @ng-bootstrap/ng-bootstrap). But to be clear I wouldn't recommend it as you would have to have different imports in your server-side and client-side code.

pkozlowski.opensource
  • 117,202
  • 60
  • 326
  • 286
  • it seems that your comment on the build issue is correct, but please be aware that any `ng-bootstrap` user following the official `ng-cli` [guide][1] will end up with the same issue. It's not clear to me yet how to resolve it, but chances are you guys would like to include something about this in your manual's Installation section. [1]: https://github.com/angular/angular-cli/wiki/stories-universal-rendering – ŁukaszBachman Aug 01 '17 at 13:41
-1

I think you can create two module. One is for browser is imported ng-bootstrap, one is for server is not imported ng-bootstrap. I think you have to create one more module common to share component, service for browser module and server module. Modal doesn't render by server to SEO.