async dev() {
    const mainProgress = progress.get('main')

    this.serverless.devmodeEnabled = true
    logger.logoDevMode()

    // Educate
    logger.blankLine()
    logger.aside(
      `Dev Mode redirects live AWS Lambda events to your local code enabling you to develop faster without the slowness of deploying changes.`,
    )
    logger.blankLine()
    logger.aside(
      `Docs: https://www.serverless.com/framework/docs/providers/aws/cli-reference/dev`,
    )
    logger.blankLine()
    logger.aside(
      `Run "serverless deploy" after a Dev Mode session to restore original code.`,
    )

    mainProgress.notice('Connecting')

    // TODO: This should be applied more selectively
    chokidar
      .watch(this.serverless.config.serviceDir, {
        ignored: /\.serverless/,
        ignoreInitial: true,
      })
      .on('all', async (event, path) => {
        await this.serverless.pluginManager.spawn('dev-build')
      })

    this.validateRegion()

    await this.update()

    this._updateHooks()

    logger.debug(
      `Spawning the deploy command to instrument your AWS Lambda functions with the dev mode shim`,
    )
    await this.serverless.pluginManager.spawn('deploy')

    this.logOutputs()

    // After the initial deployment we should run one dev-build lifecycle
    // to ensure function code is built if a build plugin is being utilized
    logger.debug(`Spawning the dev-build plugin to build the function code`)
    await this.serverless.pluginManager.spawn('dev-build')

    await this.restore()

    await this.connect()

    await this.watch()
  }
The main handler for dev mode. Steps include:
- Packaging the shim and setting it as the service deployment artifact.
- Updating the service to use the shim.
- Spawn a deployment, which will deploy the shim.
- Restoring the state to what it was before.
- Connect to IoT over websockets, and Listening for lambda events.

@async
@returns {Promise<void>} This method is long running, so it does not return a value.