MatAtBread / fast-async

605 stars 21 forks source link

SyntaxError: Strict mode does not allow function declarations in a lexically nested statement #49

Closed Cweili closed 6 years ago

Cweili commented 6 years ago

fast-async compiled code throws SyntaxError: Strict mode does not allow function declarations in a lexically nested statement in IOS 9.x.

.babelrc :

{
  "plugins": [
    [
      "transform-runtime", {
        "polyfill": false,
        "regenerator": false
      }
    ],
    [
      "fast-async", {
        "env": {
          "log": false
        },
        "compiler": {
          "promises": true,
          "generators": false,
          "noRuntime": true
        },
        "runtimePattern": null,
        "useRuntimeModule": true
      }
    ]
  ]
}

source code:

async(ctx, next) => {
  if (ctx.method != 'GET') {
    const request = serializeRequest(ctx);
    if (!requestLimits[request]) {
      await next();
    }
  } else {
    await next();
  }
}

compiled code:

function (ctx, next) {
  return new Promise(function ($return, $error) {
    var request;

    if (ctx.method != 'GET') {
      request = serializeRequest(ctx);
      if (!requestLimits[request]) {
        return next().then(function ($await_5) {
          try {
            return $If_4.call(this);
          } catch ($boundEx) {
            return $error($boundEx);
          }
        }.bind(this), $error);
      }

      function $If_4() { // throws SyntaxError: Strict mode does not allow function declarations in a lexically nested statement
        return $If_3.call(this);
      }

      return $If_4.call(this);
    } else {
      return next().then(function ($await_6) {
        try {
          return $If_3.call(this);
        } catch ($boundEx) {
          return $error($boundEx);
        }
      }.bind(this), $error);
    }

    function $If_3() {
      return $return();
    }
  }.bind(this));
}

Could you fix this? Thanks very much for your hard work.

matAtWork commented 6 years ago

This is due to the transpiled code declaring itself as strict, but not being really strict. In some cases this occurs because a third-party tool inserts a use strict into the original or transpiled code (eg webpack). Try declaring the original file as strict as well so nodent (fast-async) knows you intend to ship strict code (it doesn't if the use strict was added after compilation). The underlying cause is that iOS 9 doesn't hoist functions nested in blocks in strict mode, unlike every other JS engine out there.

See https://github.com/MatAtBread/fast-async/issues/30 for more details. The history of wh it is the way it is can be found at https://github.com/MatAtBread/nodent/issues/22