Repository: netlify/zip-it-and-ship-it
Pull request #436 (2021-04-22 13:17:41)

feat: add `mainFile` to output of `zipFunction`/`zipFunctions`
**- Summary**

Adds a `mainFile` property to the return value of the `zipFunction` and `zipFunctions` entrypoints. This makes it possible to unequivocally determine which bundles were generated from each input file, which is useful in CLI when serving bundled functions locally.

**- Test plan**

Adjusted existing tests.

**- Description for the changelog**

feat: add `mainFile` to output of `zipFunction`/`zipFunctions`

**- A picture of a cute animal (not mandatory but encouraged)**

![mqdefault](https://user-images.githubusercontent.com/4162329/115720698-3889fb00-a375-11eb-8f51-f6182c63d421.jpg)


github-actions[bot]: ## ⏱ Benchmark results

Comparing with f97938a515f56bd50a1e744bdbd8ab4240ec5c08

- **largeDepsEsbuild**: 9.1s ⬇️ (27.56% decrease)
- **largeDepsZisi**: 58.7s ⬇️ (21.35% decrease)
<!--delta:benchmark@{"largeDepsEsbuild":9160.350549666666,"largeDepsZisi":58702.18278033333}-->

Patch:
diff --git a/src/zip.js b/src/zip.js
index 2d91b49..e40ae21 100644
--- a/src/zip.js
+++ b/src/zip.js
@@ -19,13 +19,24 @@ const validateArchiveFormat = (archiveFormat) => {
 
 // Takes the result of zipping a function and formats it for output.
 const formatZipResult = (result) => {
-  const { bundler, bundlerErrors, bundlerWarnings, config = {}, name, nativeNodeModules, path, runtime } = result
+  const {
+    bundler,
+    bundlerErrors,
+    bundlerWarnings,
+    config = {},
+    mainFile,
+    name,
+    nativeNodeModules,
+    path,
+    runtime,
+  } = result
 
   return removeFalsy({
     bundler,
     bundlerErrors,
     bundlerWarnings,
     config,
+    mainFile,
     name,
     nativeNodeModules,
     path,
@@ -66,7 +77,7 @@ const zipFunctions = async function (
         stat: func.stat,
       })
 
-      return { ...zipResult, name: func.name, runtime: func.runtime }
+      return { ...zipResult, mainFile: func.mainFile, name: func.name, runtime: func.runtime }
     },
     {
       concurrency: parallelLimit,
@@ -109,7 +120,7 @@ const zipFunction = async function (
     pluginsModulesPath,
   })
 
-  return formatZipResult({ ...zipResult, name, runtime })
+  return formatZipResult({ ...zipResult, mainFile, name, runtime })
 }
 
 module.exports = { zipFunction, zipFunctions }


Test patch:
diff --git a/tests/main.js b/tests/main.js
index b7050a0..f849caf 100644
--- a/tests/main.js
+++ b/tests/main.js
@@ -59,8 +59,12 @@ test.after.always(async () => {
 const testBundlers = makeTestBundlers(test)
 
 testBundlers('Zips Node.js function files', [ESBUILD, ESBUILD_ZISI, DEFAULT], async (bundler, t) => {
-  const { files } = await zipNode(t, 'simple', { opts: { config: { '*': { nodeBundler: bundler } } } })
-  t.true(files.every(({ runtime }) => runtime === 'js'))
+  const fixtureName = 'simple'
+  const { files } = await zipNode(t, fixtureName, { opts: { config: { '*': { nodeBundler: bundler } } } })
+
+  t.is(files.length, 1)
+  t.is(files[0].runtime, 'js')
+  t.is(files[0].mainFile, join(FIXTURES_DIR, fixtureName, 'function.js'))
 })
 
 testBundlers(
@@ -350,17 +354,22 @@ testBundlers(
   'Can target a directory with a main file with the same name',
   [ESBUILD, ESBUILD_ZISI, DEFAULT],
   async (bundler, t) => {
-    await zipNode(t, 'directory-handler', { opts: { config: { '*': { nodeBundler: bundler } } } })
+    const fixtureName = 'directory-handler'
+    const { files } = await zipNode(t, fixtureName, { opts: { config: { '*': { nodeBundler: bundler } } } })
+
+    t.is(files[0].mainFile, join(FIXTURES_DIR, fixtureName, 'function', 'function.js'))
   },
 )
 
 testBundlers('Can target a directory with an index.js file', [ESBUILD, ESBUILD_ZISI, DEFAULT], async (bundler, t) => {
-  const { files, tmpDir } = await zipFixture(t, 'index-handler', {
+  const fixtureName = 'index-handler'
+  const { files, tmpDir } = await zipFixture(t, fixtureName, {
     opts: { config: { '*': { nodeBundler: bundler } } },
   })
   await unzipFiles(files)
   // eslint-disable-next-line import/no-dynamic-require, node/global-require
   t.true(require(`${tmpDir}/function.js`))
+  t.is(files[0].mainFile, join(FIXTURES_DIR, fixtureName, 'function', 'index.js'))
 })
 
 testBundlers(
@@ -481,7 +490,8 @@ testBundlers('Can reduce parallelism', [ESBUILD, ESBUILD_ZISI, DEFAULT], async (
 
 testBundlers('Can use zipFunction()', [ESBUILD, ESBUILD_ZISI, DEFAULT], async (bundler, t) => {
   const { path: tmpDir } = await getTmpDir({ prefix: 'zip-it-test' })
-  const result = await zipFunction(`${FIXTURES_DIR}/simple/function.js`, tmpDir, {
+  const mainFile = join(FIXTURES_DIR, 'simple', 'function.js')
+  const result = await zipFunction(mainFile, tmpDir, {
     config: { '*': { nodeBundler: bundler } },
   })
   const outBundlers = { [ESBUILD_ZISI]: ESBUILD, [DEFAULT]: JS_BUNDLER_ZISI }
@@ -490,6 +500,7 @@ testBundlers('Can use zipFunction()', [ESBUILD, ESBUILD_ZISI, DEFAULT], async (b
   t.is(result.name, 'function')
   t.is(result.runtime, 'js')
   t.is(result.bundler, outBundler)
+  t.is(result.mainFile, mainFile)
   t.deepEqual(result.config, bundler === DEFAULT ? {} : { nodeBundler: outBundler })
 })