0
votes

I have written a code in node.js(ES6) and below is my problem with steps i followed to run my code:

-Step1: ES6 code==>(babel)==>successfully transpiled code when run (npm run build)

-Step2: run command (npm start) throws error "SyntaxError: Unexpected token import"

But if i run "nodemon ./src/index.js --exec babel-node" it runs successfully. I have also tried to understand the reason for failure by searching similar questions on stackoverflow before posting this question here but not able to make my code work.

I really appreciate your help guys i do not know how to proceed from here, our whole production deployment is stuck due to this issue:(.

Below you will find my code files which shows i have already used babel and .babelrc in my code: Package.json-

"dependencies": {
"babel-preset-es2015": "^6.24.1",
"body-parser": "^1.16.0",
"connect-timeout": "^1.8.0",
"core-js": "^2.4.1",
"cors": "^2.8.1",
"express": "^4.14.1",
"joi": "^10.2.2",
"jsonapi-serializer": "^3.5.3",
"mongoose": "^4.10.4",
"mongoose-rename-id": "^1.0.2",
"nedb": "^1.8.0",
"path": "^0.12.7",
"randomstring": "^1.1.5",
"request": "^2.79.0",
"request-promise": "^4.1.1",
"swagger-express-mw": "^0.1.0",
"swagger-ui": "^2.2.10",
"yamljs": "^0.2.8"

},

"devDependencies": {
"babel-cli": "^6.22.2",
"babel-core": "^6.22.1",
"babel-preset-es2015": "^6.24.1",
"babel-preset-es2015-node": "^6.1.1",
"babel-preset-es2016-node4": "^6.0.1",
"babel-preset-es2017": "^6.22.0",
"chai": "^3.5.0",
"chai-as-promised": "^6.0.0",
"husky": "^0.13.1",
"mocha": "^3.2.0",
"mocha-duplicate-reporter": "^0.2.1",
"mocha-multi": "^0.9.0",
"mocha-sonar-generic-test-coverage": "0.0.1",
"nock": "^9.0.2",
"node-mocks-http": "^1.6.1",
"nodemon": "^1.11.0",
"nyc": "^10.1.2",
"pact": "^1.0.0",
"rimraf": "^2.5.4",
"sinon": "^1.17.7",
"sinon-chai": "^2.8.0",
"snazzy": "^6.0.0",
"standard": "^8.6.0",
"unit.js": "^2.0.0"

},

.babelrc-
   {
 "presets": [
    "es2016-node4",
      "es2017",
      "es2015"
     ]
   } 

code for index.js:

'use strict'
import * as path from 'path'
import {PORT} from 'config'

// config module loads the configuration from the folder the process is run
process.env[ 'NODE_CONFIG_DIR' ] = path.resolve(__dirname, '/config')

import server from './server'

// Start the server
server(PORT)

code for server.js:

import cors from 'cors'
import SwaggerExpress from 'swagger-express-mw'
import bodyParser from 'body-parser'
import timeout from 'connect-timeout'
import * as YAML from 'yamljs'
import * as path from 'path'
import account from '../src/api/controllers/accounts.js'

const version = {
file: YAML.load(path.join(__dirname, 'version.yml'))
}

var config = {
appRoot: __dirname,
swaggerFile: path.resolve(__dirname, 'api', 'swagger', 'swagger.json'),
basePath: '/api/v1',
swaggerSecurityHandlers:{
    basicAuth :async function(req, authOrSecDef, scopesOrApiKey, callback){
      try{
       //let data = true
        console.log(req.headers.authorization)

    let data = await account.authenticate(req.headers.authorization)
    if(data.statusCode==200){
        console.log(data)
        callback(null,true);
      }
      else
      callback(new Error("Access denied"))
      }catch(err){
        callback(new Error("Access denied"))
      }
     console.log("response ...."+data)
    }
}

}

export default function start (serverPort) {
SwaggerExpress.create(config, function (err, swaggerExpress) {
if (err) {
  throw err
}

var app = require('express')()

// Hack to override the host and port
app.get(path.resolve(config.basePath, '/api-docs'), function (req, res) {
  swaggerExpress.runner.swagger.host = req.get('host')
  // Set correct version for the API
  swaggerExpress.runner.swagger.info.version = version.file.build.name
  res.json(swaggerExpress.runner.swagger)
})

// Customize SwaggerUI
var swaggerUIParams = {
  swaggerUi: config.basePath + '/docs',
  apiDocs: config.basePath + '/api-docs'
}

// Add for version
app.get('/version', function (req, res) {
  // Load yaml file using YAML.load

  res.json(version.file.build)
})

// serves the Swagger documents and Swagger UI
app.use(swaggerExpress.runner.swaggerTools.swaggerUi(swaggerUIParams))

app.use(cors())

app.use(bodyParser.json())

app.use(timeout('6s'))

// install middleware
swaggerExpress.register(app)

app.listen(serverPort)
})
}

code for Accounts.js(here it actually throws the error at import statement first line):

import request from 'request-promise'

export default account()

function account() { 

return {

authenticate: async function authenticate (authheader) {
console.log("Sending call for Account")
   let temp = (authheader).split(" ")
  console.log(temp[1])
  let buf = new Buffer(temp[1], 'base64'); // create a buffer and tell it the 
data coming in is base64
  let plain_auth = buf.toString();        // read it back out as a string
  console.log("Decoded Authorization ", plain_auth);
  const cred = plain_auth.split(':')


 const options={

    uri: `http://localhost:3000/api/account/${cred[0]}`,
    json: true,
    resolveWithFullResponse: true,
    headers: {
      'Content-Type': 'application/json; charset=utf-8',
      'Accept': 'application/json; charset=utf-8'
     // 'Authorization':authheader
    },
    method: 'GET'

  }

   return request(options).then((response) => {

      console.log(response.statusCode)
      return {
        "statusCode":response.statusCode,
        "body":response.body
              }    

}).catch((err) => {
    console.log(err);
    console.log('errorstatuscode:' + err.statusCode)
});


   }



  }

}

scripts in package.json:

"scripts": {
"build:transpile": "babel src/ -d dist",
"build:copy-resources": "cp -r config dist && cp -r src/api/swagger dist/api 
&& cp src/version.yml dist",
"build": "rimraf dist && npm run build:transpile && npm run build:copy-
 resources",
"devstart": "nodemon ./src/index.js --exec babel-node",
"start": "node dist/index.js",
}
2
Clearly, the script run by npm start is trying to run the source file, not the transpiled one created by Babel. We can't tell you why that is, you need to look at your package.json and paths and such.T.J. Crowder
@T.J.Crowder Crowder after transpilation (babel src/ -d dist) Babel put the source code in dist folder and then it will run "node dist/index.js" i could see this in my console logs.> > node dist/index.js /Users/bahubali/gautam/YAG/src/api/controllers/accounts.js:3 import request from 'request-promise' ^^^^^^ SyntaxError: Unexpected token import at createScript (vm.js:56:10) at Object.runInThisContext (vm.js:97:10) at Module._compile (module.js:542:28)Gautam Malik
T.J.Crowder but if i run "nodemon ./src/index.js --exec babel-node" than it works and using a dev-dependency is production is not a good ideaGautam Malik
specify scripts in package.json explicitlyShubham
@ShubhamSingla Singla below you can find the scripts that are available in my package.json "scripts": { "build:transpile": "babel src/ -d dist", "build:copy-resources": "cp -r config dist && cp -r src/api/swagger dist/api && cp src/version.yml dist", "build": "rimraf dist && npm run build:transpile && npm run build:copy- resources", "devstart": "nodemon ./src/index.js --exec babel-node", "start": "node dist/index.js", } apologies for the messy format, please let me know if you need any other informationGautam Malik

2 Answers

1
votes

Dear all the issue is resolved now, the error is in the path defined at server.js at the below line:

-import account from '../src/api/controllers/accounts.js'

There is no issue with the babel or transpiled code, its due to the wrong path definition which tells the code to pick file accounts.js from src folder not from the transpiled code present in dist folder as a result it failed and throws the error of unexpected token import.

Now i have corrected the relative path and its working fine with npm run start as well.

Thanks you all too for your support.

-1
votes

require babel-register module start of your index.js

require('babel-register');

I think it will solve your problem.

Your npm run build work when you are bundling code, that time babel transpile your code as per your configuration provided to webpack/gulp.

But when you start server then babel does not transpile it because babel does not aware about it.