Skip to content

Commit

Permalink
fix: simplify imports/exports of ES modules (#976)
Browse files Browse the repository at this point in the history
Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
  • Loading branch information
ehmicky and kodiakhq[bot] committed Feb 8, 2022
1 parent 64089d8 commit 587a912
Show file tree
Hide file tree
Showing 69 changed files with 142 additions and 307 deletions.
17 changes: 7 additions & 10 deletions src/archive.ts
Expand Up @@ -6,20 +6,22 @@ import { promisify } from 'util'
import archiver, { Archiver } from 'archiver'
import endOfStream from 'end-of-stream'

type ArchiveFormat = 'none' | 'zip'
export { Archiver as ZipArchive } from 'archiver'

export type ArchiveFormat = 'none' | 'zip'

const pEndOfStream = promisify(endOfStream)

// Start zipping files
const startZip = function (destPath: string): { archive: Archiver; output: Writable } {
export const startZip = function (destPath: string): { archive: Archiver; output: Writable } {
const output = createWriteStream(destPath)
const archive = archiver('zip')
archive.pipe(output)
return { archive, output }
}

// Add new file to zip
const addZipFile = function (archive: Archiver, file: string, name: string, stat: Stats): void {
export const addZipFile = function (archive: Archiver, file: string, name: string, stat: Stats): void {
if (stat.isSymbolicLink()) {
const linkContent = readlinkSync(file)
archive.symlink(name, linkContent, stat.mode)
Expand All @@ -35,17 +37,12 @@ const addZipFile = function (archive: Archiver, file: string, name: string, stat
}

// Add new file content to zip
const addZipContent = function (archive: Archiver, content: Buffer | string, name: string): void {
export const addZipContent = function (archive: Archiver, content: Buffer | string, name: string): void {
archive.append(content, { name, date: new Date(0) })
}

// End zipping files
const endZip = async function (archive: Archiver, output: Writable): Promise<void> {
export const endZip = async function (archive: Archiver, output: Writable): Promise<void> {
archive.finalize()
await pEndOfStream(output)
}

export { startZip, addZipFile, addZipContent, endZip }
export type { ArchiveFormat }

export { Archiver as ZipArchive } from 'archiver'
9 changes: 3 additions & 6 deletions src/config.ts
Expand Up @@ -5,7 +5,7 @@ import { FunctionSource } from './function'
import type { NodeVersionString } from './runtimes/node'
import type { NodeBundlerName } from './runtimes/node/bundlers'

interface FunctionConfig {
export interface FunctionConfig {
externalNodeModules?: string[]
includedFiles?: string[]
includedFilesBasePath?: string
Expand All @@ -21,9 +21,9 @@ interface FunctionConfig {

type GlobPattern = string

type Config = Record<GlobPattern, FunctionConfig>
export type Config = Record<GlobPattern, FunctionConfig>

const getConfigForFunction = ({
export const getConfigForFunction = ({
config,
func,
}: {
Expand Down Expand Up @@ -56,6 +56,3 @@ const getConfigForFunction = ({

return mergeOptions.apply({ concatArrays: true, ignoreUndefined: true }, matches)
}

export { getConfigForFunction }
export type { Config, FunctionConfig }
11 changes: 4 additions & 7 deletions src/feature_flags.ts
@@ -1,6 +1,6 @@
import { env } from 'process'

const FLAGS: Record<string, boolean> = {
export const defaultFlags: Record<string, boolean> = {
buildGoSource: Boolean(env.NETLIFY_EXPERIMENTAL_BUILD_GO_SOURCE),
buildRustSource: Boolean(env.NETLIFY_EXPERIMENTAL_BUILD_RUST_SOURCE),
defaultEsModulesToEsbuild: Boolean(env.NETLIFY_EXPERIMENTAL_DEFAULT_ES_MODULES_TO_ESBUILD),
Expand All @@ -9,19 +9,16 @@ const FLAGS: Record<string, boolean> = {
zisi_pure_esm: false,
}

type FeatureFlag = keyof typeof FLAGS
type FeatureFlags = Record<FeatureFlag, boolean>
export type FeatureFlag = keyof typeof defaultFlags
export type FeatureFlags = Record<FeatureFlag, boolean>

// List of supported flags and their default value.

const getFlags = (input: Record<string, boolean> = {}, flags = FLAGS) =>
export const getFlags = (input: Record<string, boolean> = {}, flags = defaultFlags) =>
Object.entries(flags).reduce(
(result, [key, defaultValue]) => ({
...result,
[key]: input[key] === undefined ? defaultValue : input[key],
}),
{},
)

export { FLAGS as defaultFlags, getFlags }
export type { FeatureFlag, FeatureFlags }
8 changes: 3 additions & 5 deletions src/function.ts
Expand Up @@ -4,15 +4,15 @@ import type { FunctionConfig } from './config'
import type { Runtime, ZipFunctionResult } from './runtimes/runtime'

// A function that has been processed and turned into an archive.
type FunctionArchive = ZipFunctionResult & {
export type FunctionArchive = ZipFunctionResult & {
mainFile: string
name: string
runtime: Runtime
size?: number
}

// A function file found on the filesystem.
interface SourceFile {
export interface SourceFile {
extension: string
filename: string
mainFile: string
Expand All @@ -23,9 +23,7 @@ interface SourceFile {
}

// A function associated with a runtime.
type FunctionSource = SourceFile & {
export type FunctionSource = SourceFile & {
config: FunctionConfig
runtime: Runtime
}

export { FunctionArchive, FunctionSource, SourceFile }
12 changes: 5 additions & 7 deletions src/main.ts
Expand Up @@ -8,6 +8,8 @@ import { findISCDeclarationsInPath, ISCValues } from './runtimes/node/in_source_
import { GetSrcFilesFunction, RuntimeName } from './runtimes/runtime'
import { listFunctionsDirectories, resolveFunctionsDirectories } from './utils/fs'

export { zipFunction, zipFunctions } from './zip'

interface ListedFunction {
name: string
mainFile: string
Expand Down Expand Up @@ -42,7 +44,7 @@ const augmentWithISC = async (func: FunctionSource): Promise<AugmentedFunctionSo
}

// List all Netlify Functions main entry files for a specific directory
const listFunctions = async function (
export const listFunctions = async function (
relativeSrcFolders: string | string[],
{
featureFlags: inputFeatureFlags,
Expand All @@ -60,7 +62,7 @@ const listFunctions = async function (
}

// Finds a function at a specific path.
const listFunction = async function (
export const listFunction = async function (
path: string,
{
featureFlags: inputFeatureFlags,
Expand All @@ -80,7 +82,7 @@ const listFunction = async function (
}

// List all Netlify Functions files for a specific directory
const listFunctionsFiles = async function (
export const listFunctionsFiles = async function (
relativeSrcFolders: string | string[],
{ basePath, config, featureFlags: inputFeatureFlags, parseISC = false }: ListFunctionsOptions = {},
) {
Expand Down Expand Up @@ -130,7 +132,3 @@ const getSrcFiles: GetSrcFilesFunction = async function ({ extension, runtime, s
...args,
})
}

export { listFunctions, listFunction, listFunctionsFiles }

export { zipFunction, zipFunctions } from './zip'
7 changes: 2 additions & 5 deletions src/manifest.ts
Expand Up @@ -12,7 +12,7 @@ interface ManifestFunction {
schedule?: string
}

interface Manifest {
export interface Manifest {
functions: ManifestFunction[]
system: {
arch: string
Expand All @@ -24,7 +24,7 @@ interface Manifest {

const MANIFEST_VERSION = 1

const createManifest = async ({ functions, path }: { functions: FunctionResult[]; path: string }) => {
export const createManifest = async ({ functions, path }: { functions: FunctionResult[]; path: string }) => {
const formattedFunctions = functions.map(formatFunctionForManifest)
const payload: Manifest = {
functions: formattedFunctions,
Expand All @@ -43,6 +43,3 @@ const formatFunctionForManifest = ({ mainFile, name, path, runtime, schedule }:
runtime,
schedule,
})

export { createManifest }
export type { Manifest }
4 changes: 1 addition & 3 deletions src/runtimes/detect_runtime.ts
Expand Up @@ -7,7 +7,7 @@ import { cachedReadFile, FsCache } from '../utils/fs'
import type { RuntimeName } from './runtime'

// Try to guess the runtime by inspecting the binary file.
const detectBinaryRuntime = async function ({
export const detectBinaryRuntime = async function ({
fsCache,
path,
}: {
Expand All @@ -32,5 +32,3 @@ const detectBinaryRuntime = async function ({
}
} catch {}
}

export { detectBinaryRuntime }
4 changes: 1 addition & 3 deletions src/runtimes/go/builder.ts
Expand Up @@ -4,7 +4,7 @@ import { basename } from 'path'
import { shellUtils } from '../../utils/shell'
import type { RuntimeName } from '../runtime'

const build = async ({ destPath, mainFile, srcDir }: { destPath: string; mainFile: string; srcDir: string }) => {
export const build = async ({ destPath, mainFile, srcDir }: { destPath: string; mainFile: string; srcDir: string }) => {
const functionName = basename(srcDir)

try {
Expand Down Expand Up @@ -34,5 +34,3 @@ const build = async ({ destPath, mainFile, srcDir }: { destPath: string; mainFil
stat,
}
}

export { build }
6 changes: 2 additions & 4 deletions src/runtimes/index.ts
Expand Up @@ -75,7 +75,7 @@ const RUNTIMES = [jsRuntime, goRuntime, rustRuntime]
/**
* Gets a list of functions found in a list of paths.
*/
const getFunctionsFromPaths = async (
export const getFunctionsFromPaths = async (
paths: string[],
{
config,
Expand Down Expand Up @@ -115,7 +115,7 @@ const getFunctionsFromPaths = async (
/**
* Gets a list of functions found in a list of paths.
*/
const getFunctionFromPath = async (
export const getFunctionFromPath = async (
path: string,
{ config, featureFlags = defaultFlags }: { config?: Config; featureFlags?: FeatureFlags } = {},
): Promise<FunctionSource | undefined> => {
Expand All @@ -134,5 +134,3 @@ const getFunctionFromPath = async (

return undefined
}

export { getFunctionsFromPaths, getFunctionFromPath }
6 changes: 2 additions & 4 deletions src/runtimes/node/bundlers/esbuild/bundler.ts
Expand Up @@ -16,14 +16,14 @@ import { getNodeBuiltinPlugin } from './plugin_node_builtin'
// Maximum number of log messages that an esbuild instance will produce. This
// limit is important to avoid out-of-memory errors due to too much data being
// sent in the Go<>Node IPC channel.
const ESBUILD_LOG_LIMIT = 10
export const ESBUILD_LOG_LIMIT = 10

// When resolving imports with no extension (e.g. require('./foo')), these are
// the extensions that esbuild will look for, in this order.
const RESOLVE_EXTENSIONS = ['.js', '.jsx', '.mjs', '.cjs', '.ts', '.json']

// eslint-disable-next-line max-statements
const bundleJsFile = async function ({
export const bundleJsFile = async function ({
additionalModulePaths,
basePath,
config,
Expand Down Expand Up @@ -173,5 +173,3 @@ const getBundlePaths = ({
const getCleanupFunction = (paths: string[]) => async () => {
await Promise.all(paths.filter(Boolean).map(safeUnlink))
}

export { bundleJsFile, ESBUILD_LOG_LIMIT }
4 changes: 1 addition & 3 deletions src/runtimes/node/bundlers/esbuild/bundler_target.ts
Expand Up @@ -10,7 +10,7 @@ const versionMap = {
type VersionKeys = keyof typeof versionMap
type VersionValues = typeof versionMap[VersionKeys]

const getBundlerTarget = (suppliedVersion?: string): VersionValues => {
export const getBundlerTarget = (suppliedVersion?: string): VersionValues => {
const version = normalizeVersion(suppliedVersion)

if (version && version in versionMap) {
Expand All @@ -25,5 +25,3 @@ const normalizeVersion = (version?: string) => {

return match ? match[1] : version
}

export { getBundlerTarget }
4 changes: 1 addition & 3 deletions src/runtimes/node/bundlers/esbuild/plugin_dynamic_imports.ts
Expand Up @@ -16,7 +16,7 @@ type PackageCache = Map<string, Promise<string | undefined>>
// issues. Secondly, it parses the dynamic expressions and tries to include in
// the bundle all the files that are possibly needed to make the import work at
// runtime. This is not always possible, but we do our best.
const getDynamicImportsPlugin = ({
export const getDynamicImportsPlugin = ({
basePath,
includedPaths,
moduleNames,
Expand Down Expand Up @@ -153,5 +153,3 @@ const registerModuleWithDynamicImports = async ({
// no-op
}
}

export { getDynamicImportsPlugin }
4 changes: 1 addition & 3 deletions src/runtimes/node/bundlers/esbuild/plugin_native_modules.ts
Expand Up @@ -28,7 +28,7 @@ const findNativeModule = (packageJsonPath: string, cache: NativeModuleCache) =>
return cache[packageJsonPath]
}

const getNativeModulesPlugin = (externalizedModules: NativeNodeModules): Plugin => ({
export const getNativeModulesPlugin = (externalizedModules: NativeNodeModules): Plugin => ({
name: 'external-native-modules',
setup(build) {
const cache: NativeModuleCache = {}
Expand Down Expand Up @@ -78,5 +78,3 @@ const getNativeModulesPlugin = (externalizedModules: NativeNodeModules): Plugin
})
},
})

export { getNativeModulesPlugin }
4 changes: 1 addition & 3 deletions src/runtimes/node/bundlers/esbuild/plugin_node_builtin.ts
@@ -1,10 +1,8 @@
import type { Plugin } from '@netlify/esbuild'

const getNodeBuiltinPlugin = (): Plugin => ({
export const getNodeBuiltinPlugin = (): Plugin => ({
name: 'builtin-modules',
setup(build) {
build.onResolve({ filter: /^node:/ }, (args) => ({ path: args.path.slice('node:'.length), external: true }))
},
})

export { getNodeBuiltinPlugin }
4 changes: 1 addition & 3 deletions src/runtimes/node/bundlers/esbuild/special_cases.ts
Expand Up @@ -14,7 +14,7 @@ const getModulesForNextJs = ({ dependencies, devDependencies }: PackageJson) =>
}
}

const getExternalAndIgnoredModulesFromSpecialCases = async ({ srcDir }: { srcDir: string }) => {
export const getExternalAndIgnoredModulesFromSpecialCases = async ({ srcDir }: { srcDir: string }) => {
const { dependencies = {}, devDependencies = {} } = await getPackageJsonIfAvailable(srcDir)
const { externalModules: nextJsExternalModules, ignoredModules: nextJsIgnoredModules } = getModulesForNextJs({
dependencies,
Expand All @@ -28,5 +28,3 @@ const getExternalAndIgnoredModulesFromSpecialCases = async ({ srcDir }: { srcDir
ignoredModules,
}
}

export { getExternalAndIgnoredModulesFromSpecialCases }
4 changes: 1 addition & 3 deletions src/runtimes/node/bundlers/esbuild/src_files.ts
Expand Up @@ -4,7 +4,7 @@ import { getPackageJson, PackageJson } from '../../utils/package_json'
import { getNewCache, TraversalCache } from '../../utils/traversal_cache'
import { getDependencyPathsForDependency } from '../zisi/traverse'

const getSrcFiles: GetSrcFilesFunction = async ({ config, mainFile, pluginsModulesPath, srcDir }) => {
export const getSrcFiles: GetSrcFilesFunction = async ({ config, mainFile, pluginsModulesPath, srcDir }) => {
const { externalNodeModules = [], includedFiles = [], includedFilesBasePath } = config
const { exclude: excludedPaths, paths: includedFilePaths } = await getPathsOfIncludedFiles(
includedFiles,
Expand Down Expand Up @@ -77,5 +77,3 @@ const getSrcFilesForDependency = async function ({
throw error
}
}

export { getSrcFiles }

1 comment on commit 587a912

@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: 6.8s

largeDepsNft: 30.3s

largeDepsZisi: 57.8s

Please sign in to comment.