Skip to content
This repository has been archived by the owner on May 22, 2024. It is now read-only.

Commit

Permalink
feat: add nativeNodeModules property to output (#433)
Browse files Browse the repository at this point in the history
* feat: add function name to output of zipFunction and zipFunctions

* feat: add detected native node modules to return value

* chore: disable tests for Node 8

* chore: add debug statement

* chore: remove debug statement
  • Loading branch information
eduardoboucas committed Apr 20, 2021
1 parent d31d739 commit cfec60f
Show file tree
Hide file tree
Showing 6 changed files with 44 additions and 19 deletions.
6 changes: 3 additions & 3 deletions src/runtimes/node/bundler.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ const bundleJsFile = async function ({
}
}

const externalizedModules = new Set()
const plugins = [externalNativeModulesPlugin(externalizedModules)]
const nativeNodeModules = {}
const plugins = [externalNativeModulesPlugin(nativeNodeModules)]
const nodeTarget = getBundlerTarget(config.nodeVersion)

try {
Expand All @@ -58,7 +58,7 @@ const bundleJsFile = async function ({
target: [nodeTarget],
})

return { bundlePath, cleanTempFiles, data, externalizedModules: [...externalizedModules] }
return { bundlePath, cleanTempFiles, data, nativeNodeModules }
} catch (error) {
error.customErrorInfo = { type: 'functionsBundling', location: { functionName: name } }

Expand Down
18 changes: 13 additions & 5 deletions src/runtimes/node/native_modules/plugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ const findNativeModule = (packageJsonPath, cache) => {
if (cache[packageJsonPath] === undefined) {
// eslint-disable-next-line fp/no-mutation, no-param-reassign, promise/prefer-await-to-then
cache[packageJsonPath] = readPackageJson(packageJsonPath).then(
(data) => Boolean(isNativeModule(data)),
() => {},
(data) => [Boolean(isNativeModule(data), data), data],
() => [],
)
}

Expand All @@ -39,13 +39,21 @@ const externalNativeModulesPlugin = (externalizedModules) => ({
// eslint-disable-next-line fp/no-loops
while (true) {
if (path.basename(directory) !== 'node_modules') {
const packageJsonPath = path.join(directory, 'node_modules', package[1], 'package.json')
const modulePath = path.join(directory, 'node_modules', package[1])
const packageJsonPath = path.join(modulePath, 'package.json')
// eslint-disable-next-line no-await-in-loop
const isNative = await findNativeModule(packageJsonPath, cache)
const [isNative, packageJsonData] = await findNativeModule(packageJsonPath, cache)

// eslint-disable-next-line max-depth
if (isNative === true) {
externalizedModules.add(args.path)
// eslint-disable-next-line max-depth
if (externalizedModules[args.path] === undefined) {
// eslint-disable-next-line fp/no-mutation, no-param-reassign
externalizedModules[args.path] = {}
}

// eslint-disable-next-line fp/no-mutation, no-param-reassign
externalizedModules[args.path][modulePath] = packageJsonData.version

return { path: args.path, external: true }
}
Expand Down
6 changes: 3 additions & 3 deletions src/runtimes/node/zip_esbuild.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ const zipEsbuild = async ({
stat,
}) => {
const { externalModules, ignoredModules } = await getExternalAndIgnoredModules({ config, srcDir })
const { bundlePath, data, cleanTempFiles, externalizedModules } = await bundleJsFile({
const { bundlePath, data, cleanTempFiles, nativeNodeModules = {} } = await bundleJsFile({
additionalModulePaths: pluginsModulesPath ? [pluginsModulesPath] : [],
config,
destFilename: filename,
Expand All @@ -53,7 +53,7 @@ const zipEsbuild = async ({
})
const bundlerWarnings = data.warnings.length === 0 ? undefined : data.warnings
const { paths: srcFiles } = await getSrcFilesAndExternalModules({
externalNodeModules: [...externalModules, ...externalizedModules],
externalNodeModules: [...externalModules, ...Object.keys(nativeNodeModules)],
bundler: JS_BUNDLER_ESBUILD,
mainFile,
srcPath,
Expand Down Expand Up @@ -92,7 +92,7 @@ const zipEsbuild = async ({
srcFiles: [...supportingSrcFiles, bundlePath],
})

return { bundler: JS_BUNDLER_ESBUILD, bundlerWarnings, config, path }
return { bundler: JS_BUNDLER_ESBUILD, bundlerWarnings, config, nativeNodeModules, path }
} finally {
await cleanTempFiles()
}
Expand Down
3 changes: 2 additions & 1 deletion src/zip.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,15 @@ const validateArchiveFormat = (archiveFormat) => {

// Takes the result of zipping a function and formats it for output.
const formatZipResult = (result) => {
const { bundler, bundlerErrors, bundlerWarnings, config = {}, name, path, runtime } = result
const { bundler, bundlerErrors, bundlerWarnings, config = {}, name, nativeNodeModules, path, runtime } = result

return removeFalsy({
bundler,
bundlerErrors,
bundlerWarnings,
config,
name,
nativeNodeModules,
path,
runtime: runtime.name,
})
Expand Down
2 changes: 1 addition & 1 deletion tests/fixtures/node-module-native-buildtime/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@
"name": "node-module-native-buildtime",
"version": "1.0.0",
"dependencies": {
"test": "1.0.2"
"test": "1.0.0"
}
}
28 changes: 22 additions & 6 deletions tests/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,45 +67,61 @@ testBundlers(
'Handles Node module with native bindings (buildtime marker module)',
[ESBUILD, ESBUILD_ZISI, DEFAULT],
async (bundler, t) => {
if (bundler === ESBUILD && semver.lt(versions.node, '10.0.0')) {
if (semver.lt(versions.node, '10.0.0')) {
t.log('Skipping test for unsupported Node version')

return t.pass()
}

const { files, tmpDir } = await zipNode(t, 'node-module-native-buildtime', {
const fixtureDir = 'node-module-native-buildtime'
const { files, tmpDir } = await zipNode(t, fixtureDir, {
opts: { config: { '*': { nodeBundler: bundler } } },
})
const requires = await getRequires({ filePath: resolve(tmpDir, 'src/function.js') })
const normalizedRequires = new Set(requires.map(unixify))
const modulePath = resolve(FIXTURES_DIR, `${fixtureDir}/node_modules/test`)

t.true(files.every(({ runtime }) => runtime === 'js'))
t.is(files.length, 1)
t.is(files[0].runtime, 'js')
t.true(await pathExists(`${tmpDir}/src/node_modules/test/native.node`))
t.true(await pathExists(`${tmpDir}/src/node_modules/test/side-file.js`))
t.true(normalizedRequires.has('test'))

// We can only detect native modules when using esbuild.
if (bundler !== DEFAULT) {
t.deepEqual(files[0].nativeNodeModules, { test: { [modulePath]: '1.0.0' } })
}
},
)

testBundlers(
'Handles Node module with native bindings (runtime marker module)',
[ESBUILD, ESBUILD_ZISI, DEFAULT],
async (bundler, t) => {
if (bundler === ESBUILD && semver.lt(versions.node, '10.0.0')) {
if (semver.lt(versions.node, '10.0.0')) {
t.log('Skipping test for unsupported Node version')

return t.pass()
}

const { files, tmpDir } = await zipNode(t, 'node-module-native-runtime', {
const fixtureDir = 'node-module-native-runtime'
const { files, tmpDir } = await zipNode(t, fixtureDir, {
opts: { config: { '*': { nodeBundler: bundler } } },
})
const requires = await getRequires({ filePath: resolve(tmpDir, 'src/function.js') })
const normalizedRequires = new Set(requires.map(unixify))
const modulePath = resolve(FIXTURES_DIR, `${fixtureDir}/node_modules/test`)

t.true(files.every(({ runtime }) => runtime === 'js'))
t.is(files.length, 1)
t.is(files[0].runtime, 'js')
t.true(await pathExists(`${tmpDir}/src/node_modules/test/native.node`))
t.true(await pathExists(`${tmpDir}/src/node_modules/test/side-file.js`))
t.true(normalizedRequires.has('test'))

// We can only detect native modules when using esbuild.
if (bundler !== DEFAULT) {
t.deepEqual(files[0].nativeNodeModules, { test: { [modulePath]: '1.0.0' } })
}
},
)

Expand Down

1 comment on commit cfec60f

@github-actions
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⏱ Benchmark results

  • largeDepsEsbuild: 12.2s
  • largeDepsZisi: 1m 14.6s

Please sign in to comment.