async _build(handlerPropertyName = 'handler') {
    const functionsToBuild = await this.functions(handlerPropertyName)

    if (Object.keys(functionsToBuild).length === 0) {
      log.debug('No functions to build with esbuild')
      return
    }

    const updatedFunctionsToBuild = {}

    const buildProperties = await this._buildProperties()

    for (const [alias, functionObject] of Object.entries(functionsToBuild)) {
      const functionName = path
        .extname(functionObject[handlerPropertyName])
        .slice(1)
      const handlerPath = functionObject[handlerPropertyName].replace(
        `.${functionName}`,
        '',
      )
      const runtime =
        functionObject.runtime || this.serverless.service.provider.runtime

      const external = (await this._externals(runtime)).external

      const extension = await this._extensionForFunction(
        functionObject[handlerPropertyName],
      )
      if (extension) {
        // Enrich the functionObject with additional values we will need for building
        updatedFunctionsToBuild[alias] = {
          ...functionObject,
          handlerPath: path.join(
            this.serverless.config.serviceDir,
            handlerPath + extension,
          ),
          extension,
          esbuild: {
            external,
          },
        }
      }
    }

    // Determine the concurrency to use for building functions, by default framework will attempt to build
    // all functions concurrently, but this can be overridden by setting the buildConcurrency property.
    const concurrency =
      buildProperties.buildConcurrency ?? Object.keys(functionsToBuild).length

    const limit = pLimit(concurrency)

    try {
      await Promise.all(
        Object.entries(updatedFunctionsToBuild).map(
          ([alias, functionObject]) => {
            return limit(async () => {
              const functionName = path
                .extname(functionObject[handlerPropertyName])
                .slice(1)
              const handlerPath = functionObject[handlerPropertyName].replace(
                `.${functionName}`,
                '',
              )
              const esbuildProps = {
                ...buildProperties,
                platform: 'node',
                ...(buildProperties.bundle === true
                  ? { external: functionObject.esbuild.external }
                  : { external: [] }),
                entryPoints: [functionObject.handlerPath],
                outfile: path.join(
                  this.serverless.config.serviceDir,
                  '.serverless',
                  'build',
                  handlerPath + '.js',
                ),
                logLevel: 'error',
              }

              // Remove the following properties from the esbuildProps as they are not valid esbuild properties
              delete esbuildProps.exclude
              delete esbuildProps.buildConcurrency
              delete esbuildProps.configFile

              await esbuild.build(esbuildProps)
              if (!this.serverless.builtFunctions) {
                this.serverless.builtFunctions = new Set()
              }
              this.serverless.builtFunctions.add(alias)
              if (
                this.serverless.service.build?.esbuild?.sourcemap ===
                  undefined ||
                this.serverless.service.build?.esbuild?.sourcemap === true ||
                this.serverless.service.build?.esbuild.sourcemap
                  ?.setNodeOptions === true
              ) {
                const functionObject =
                  this.serverless.service.getFunction(alias)
                if (functionObject.environment?.NODE_OPTIONS) {
                  functionObject.environment.NODE_OPTIONS = `${functionObject.environment.NODE_OPTIONS} --enable-source-maps`
                } else {
                  if (!functionObject.environment) {
                    functionObject.environment = {}
                  }
                  functionObject.environment.NODE_OPTIONS =
                    '--enable-source-maps'
                }
              }
            })
          },
        ),
      )
    } catch (err) {
      if (this.serverless.devmodeEnabled === true) {
        return
      }
      throw new ServerlessError(err.message, 'ESBULD_BUILD_ERROR')
    }

    return
  }
Take the current build context. Which could be service-wide or a given function and then build it
@param {string} handlerPropertyName - The property name of the handler in the function object. In the case of dev mode this will be different, so we need to be able to set it.