aws-amplify / amplify-cli

The AWS Amplify CLI is a toolchain for simplifying serverless web and mobile development.
Apache License 2.0
2.81k stars 821 forks source link

Error init environment : unexpected token 'export' #10101

Closed OlgaMaslova closed 2 years ago

OlgaMaslova commented 2 years ago

Before opening, please confirm:

How did you install the Amplify CLI?

npm

If applicable, what version of Node.js are you using?

v16.13.2

Amplify CLI Version

7.6.26

What operating system are you using?

Windows

Did you make any manual changes to the cloud resources managed by Amplify? Please describe the changes made.

Nothing

Amplify Categories

Not applicable

Amplify Commands

pull

Describe the bug

No changes were performed locally. Error while performing amplify pull:

✔ Successfully pulled backend environment newdev from the cloud.
✖ There was an error initializing your environment.
Unexpected token 'export'
C:\Users\**\Documents\**\code\**\src\aws-exports.js:58
export default awsmobile;
^^^^^^

SyntaxError: Unexpected token 'export'
    at compileFunction (<anonymous>)
    at Object.compileFunction (node:vm:352:18)
    at wrapSafe (node:internal/modules/cjs/loader:1031:15)
    at Module._compile (node:internal/modules/cjs/loader:1065:27)
    at Object.Module._extensions..js (node:internal/modules/cjs/loader:1153:10)
    at Module.load (node:internal/modules/cjs/loader:981:32)
    at Function.Module._load (node:internal/modules/cjs/loader:822:12)
    at Module.require (node:internal/modules/cjs/loader:1005:19)
    at require (node:internal/modules/cjs/helpers:102:18)
rc\extensions\amplify-helpers\on-category-outputs-change.ts:21:33)    at initializeEnv (C:\Users\**\AppData\Roaming\npm\node_modules\@aws-amplify\cli\src\initialize-env.ts:103:27)
    at runMicrotasks (<anonymous>)    at processTicksAndRejections (node:internal/process/task_queues:96:5)
    at pullBackend (C:\Users\**\AppData\Roaming\npm\node_modules\@aws-amplify\cli\src\pull-backend.ts:33:3)    at Object.run (C:\Users\**\AppData\Roaming\npm\node_modules\@aws-amplify\cli\src\commands\pull.ts:60:7)
    at Object.executeAmplifyCommand (C:\Users\**\AppData\Roaming\npm\node_modules\@aws-amplify\cli\src\index.ts:373:5)    at executePluginModuleCommand (C:\Users\**\AppData\Roaming\npm\node_modules\@aws-amplify\cli\src\execution-manager.ts:178:3)
    at executeCommand (C:\Users\**\AppData\Roaming\npm\node_modules\@aws-amplify\cli\src\execution-manager.ts:30:5)    at Object.run (C:\Users\**\AppData\Roaming\npm\node_modules\@aws-amplify\cli\src\index.ts:205:5)

Expected behavior

Enviromnent initialized without error.

Reproduction steps

  1. amplify pull

GraphQL schema(s)

```graphql # Put schemas below this line ```

Log output

``` # Put your logs below this line ```

Additional information

aws-exports.js

/* eslint-disable */
// WARNING: DO NOT EDIT. This file is automatically generated by AWS Amplify. It will be overwritten.

const awsmobile = {
    "aws_project_region": "eu-west-1",
    "aws_cognito_identity_pool_id": "eu-west-1:***",
    "aws_cognito_region": "eu-west-1",
    "aws_user_pools_id": "eu-west-1_***",
    "aws_user_pools_web_client_id": "***",
    "oauth": {},
    "aws_cognito_username_attributes": [
        "EMAIL"
    ],
    "aws_cognito_social_providers": [],
    "aws_cognito_signup_attributes": [
        "EMAIL",
        "FAMILY_NAME",
        "LOCALE",
        "GIVEN_NAME",
        "ZONEINFO"
    ],
    "aws_cognito_mfa_configuration": "OPTIONAL",
    "aws_cognito_mfa_types": [
        "SMS",
        "TOTP"
    ],
    "aws_cognito_password_protection_settings": {
        "passwordPolicyMinLength": 8,
        "passwordPolicyCharacters": []
    },
    "aws_cognito_verification_mechanisms": [
        "EMAIL"
    ],
    "aws_cloud_logic_custom": [
        {
            "name": "AdminQueries",
            "endpoint": "https://***.execute-api.eu-west-1.amazonaws.com/newdev",
            "region": "eu-west-1"
        },
        {
            "name": "***Api",
            "endpoint": "https://***.execute-api.eu-west-1.amazonaws.com/newdev",
            "region": "eu-west-1"
        }
    ],
    "aws_appsync_graphqlEndpoint": "https://***.appsync-api.eu-west-1.amazonaws.com/graphql",
    "aws_appsync_region": "eu-west-1",
    "aws_appsync_authenticationType": "AMAZON_COGNITO_USER_POOLS",
    "aws_appsync_apiKey": "***",
    "aws_user_files_s3_bucket": "***-newdev",
    "aws_user_files_s3_bucket_region": "eu-west-1",
    "aws_cognito_login_mechanisms": [
        "EMAIL"
    ]
};

export default awsmobile;
josefaidt commented 2 years ago

Hey @OlgaMaslova :wave: thanks for raising this! This seems related to https://github.com/aws-amplify/amplify-cli/issues/10071. To clarify, are you seeing this when running amplify pull in an existing, initialized application locally?

OlgaMaslova commented 2 years ago

Hi @josefaidt It does look similar, yes. Although the env existed already, everything was working couple of days ago. Btw the same error appears on amplify push.

josefaidt commented 2 years ago

Btw the same error appears on amplify push.

This is a great note. Did this just start occurring? What changes were performed prior to receiving this?

OlgaMaslova commented 2 years ago

The project was updated Angular 12-> 13. Apart of that I cannot think of anything else. And the weirdest thing is that all modifications are taken into account (pull and push). Just in the end I am having this error.

josefaidt commented 2 years ago

Hey @OlgaMaslova :wave: I was able to reproduce this by removing the newline after export default awsmobile;. Can you confirm whether adding a newline after the export line mitigates the issue for you?

josefaidt commented 2 years ago

Investigating this a bit further it appears to error out in the code here https://github.com/aws-amplify/amplify-cli/blob/master/packages/amplify-frontend-javascript/lib/frontend-config-creator.js#L265-L286

Where the affected code is

const es5export = 'module.exports = {default: awsmobile};\n';
const es6export = 'export default awsmobile;\n';

If our aws-exports.js file does not end with the following export default and the new line, it will error out with unexpected token 'export' as documented here.

export default awsmobile;

NOTE for fix: if we were to instead make a temporary copy of the aws-exports.js file as aws-exports.mjs, this file will always be treated as ESM and enable us to use dynamic import to read, which may also fix the issue with updating this file in an ESM project where we have "type": "module" in the root package.json. The following is a test script used as a proof-of-concept:

import * as fs from 'node:fs/promises'

const targetFilePath = new URL('aws-exports.js', import.meta.url).pathname

async function exists(filePath) {
  try {
    await fs.access(filePath)
    return true
  } catch (error) {
    return false
  }
}

async function getCurrentAWSExports() {
  let awsExports
  if (await exists(targetFilePath)) {
    // temporary mjs file
    const mjs = new URL('amplify/aws-exports.mjs', import.meta.url).pathname
    // copy existing aws-exports.js as aws-exports.mjs
    await fs.copyFile(targetFilePath, mjs)
    // once .mjs, file is always treated as ESM and we can use dynamic import
    const mod = await import(mjs)
    if (mod?.default) {
      awsExports = mod.default
    } else {
      awsExports = mod
    }
    // rm temporary mjs file
    await fs.unlink(mjs)
  }
  return awsExports
}

const awsExports = await getCurrentAWSExports()
console.log({ awsExports })

EDIT for relevancy https://github.com/vercel/pkg/issues/1291

OlgaMaslova commented 2 years ago

Hey @OlgaMaslova 👋 I was able to reproduce this by removing the newline after export default awsmobile;. Can you confirm whether adding a newline after the export line mitigates the issue for you?

Hi @josefaidt still having the issue: with or without the new line after the export line.

I checked the history of the aws-exports.js file in my repo. It hasn't been changed for 4 months... So the problem does not come from the file, I guess?

josefaidt commented 2 years ago

Hey @OlgaMaslova this logic was recently updated in the CLI. To confirm, can you add this Node.js script to the root of your project and try running it?

const fs = require('fs')
const path = require('path')

const targetFilePath = path.join(__dirname, 'src/aws-exports.js')

async function getCurrentAWSExports(context) {
  let awsExports = {}

  if (fs.existsSync(targetFilePath)) {
    // if packaged, we can't load an ES6 module because pkg doesn't support it yet, https://github.com/vercel/pkg/issues/1291
    const es5export = 'module.exports = {default: awsmobile};\n'
    const es6export = 'export default awsmobile;\n'
    const fileContents = fs.readFileSync(targetFilePath, 'utf-8')
    fs.writeFileSync(targetFilePath, fileContents.replace(es6export, es5export))
    awsExports = require(targetFilePath).default
    fs.writeFileSync(targetFilePath, fileContents)
  }

  return awsExports
}

getCurrentAWSExports().then(console.log).catch(console.error)
OlgaMaslova commented 2 years ago

Hey @josefaidt, here is the result: image

For information the aws-exports.js does have a new line: image

josefaidt commented 2 years ago

Ah thank you for the swift test @OlgaMaslova ! Can you try modifying the script to use os.EOL as shown below? I believe this may be an issue that affects files without semicolons, newlines \n, and Windows newlines \r\n

const fs = require('fs')
const os = require('os')
const path = require('path')

const targetFilePath = path.join(__dirname, 'src/aws-exports.js')

async function getCurrentAWSExports(context) {
  let awsExports = {}

  if (fs.existsSync(targetFilePath)) {
    // if packaged, we can't load an ES6 module because pkg doesn't support it yet, https://github.com/vercel/pkg/issues/1291
    const es5export = `module.exports = {default: awsmobile};${os.EOL}`
    const es6export = `export default awsmobile;${os.EOL}`
    const fileContents = fs.readFileSync(targetFilePath, 'utf-8')
    fs.writeFileSync(targetFilePath, fileContents.replace(es6export, es5export))
    awsExports = require(targetFilePath).default
    fs.writeFileSync(targetFilePath, fileContents)
  }

  return awsExports
}

getCurrentAWSExports().then(console.log).catch(console.error)
OlgaMaslova commented 2 years ago

@josefaidt Yes! No error now! Prints the content of the aws-exports.js.

josefaidt commented 2 years ago

Hey @OlgaMaslova glad to hear that worked for you! If you're open to contributing this is a great first issue to tackle 🙂

OlgaMaslova commented 2 years ago

Hi @josefaidt , that's would be a premiere. I'll try to contribute soon! Thanks for you help on the issue.

lazpavel commented 2 years ago

revert PR: https://github.com/aws-amplify/amplify-cli/pull/10209 as 10147 breaks windows e2e tests

OlgaMaslova commented 2 years ago

Hi @josefaidt! Any progress on that? Still having this issue...

smachesney1991 commented 2 years ago

Hi @josefaidt !! This issue is back on the latest version

basedafdev commented 2 years ago

+1

erikologic commented 2 years ago

+1

nick-0101 commented 2 years ago

I was also getting this error when pulling from amplify. I was able to solve it by deleting the src folder which contained aws-exports.js and then re-running amplify pull.

amplify pull regenerates the folder but I'm still not sure what the problem was.

laclance commented 2 years ago

Changing file to .ts worked for me.