@netlify/zip-it-and-ship-it
Version:
76 lines (75 loc) • 3.24 kB
JavaScript
import { dirname, extname, normalize } from 'path';
import { FunctionBundlingUserError } from '../../../../utils/error.js';
import { RUNTIME } from '../../../runtime.js';
import { getBasePath } from '../../utils/base_path.js';
import { filterExcludedPaths, getPathsOfIncludedFiles } from '../../utils/included_files.js';
import { MODULE_FORMAT } from '../../utils/module_format.js';
import { getNodeSupportMatrix } from '../../utils/node_version.js';
import { getPackageJsonIfAvailable } from '../../utils/package_json.js';
import { NODE_BUNDLER } from '../types.js';
/**
* This bundler is a simple no-op bundler, that does no bundling at all.
* It returns the detected moduleFormat and the mainFile + includedFiles from the config.
*/
// Uses the same algorithm as the ESM_FILE_FORMAT resolver from Node.js to get
// the right module format for a function based on its main file.
// See https://nodejs.org/api/esm.html#resolver-algorithm-specification.
const getModuleFormat = async function (mainFile) {
const extension = extname(mainFile);
if (extension === '.mjs') {
return MODULE_FORMAT.ESM;
}
if (extension === '.cjs') {
return MODULE_FORMAT.COMMONJS;
}
const packageJson = await getPackageJsonIfAvailable(dirname(mainFile));
if (packageJson.type === 'module') {
return MODULE_FORMAT.ESM;
}
return MODULE_FORMAT.COMMONJS;
};
export const getSrcFiles = async function ({ config, mainFile }) {
const { includedFiles = [], includedFilesBasePath } = config;
const { excludePatterns, paths: includedFilePaths } = await getPathsOfIncludedFiles(includedFiles, includedFilesBasePath);
const includedPaths = filterExcludedPaths(includedFilePaths, excludePatterns);
return { srcFiles: [mainFile, ...includedPaths], includedFiles: includedPaths };
};
const bundle = async ({ basePath, config, extension, featureFlags, filename, mainFile, name, pluginsModulesPath, runtime, srcDir, srcPath, stat, }) => {
const { srcFiles, includedFiles } = await getSrcFiles({
basePath,
config: {
...config,
includedFilesBasePath: config.includedFilesBasePath || basePath,
},
extension,
featureFlags,
filename,
mainFile,
name,
pluginsModulesPath,
runtime,
srcDir,
srcPath,
stat,
});
const dirnames = srcFiles.map((filePath) => normalize(dirname(filePath)));
const moduleFormat = await getModuleFormat(mainFile);
const nodeSupport = getNodeSupportMatrix(config.nodeVersion);
if (moduleFormat === MODULE_FORMAT.ESM && !nodeSupport.esm) {
throw new FunctionBundlingUserError(`Function file is an ES module, which the Node.js version specified in the config (${config.nodeVersion}) does not support. ES modules are supported as of version 14 of Node.js.`, {
functionName: name,
runtime: RUNTIME.JAVASCRIPT,
bundler: NODE_BUNDLER.NONE,
});
}
return {
basePath: getBasePath(dirnames),
includedFiles,
inputs: srcFiles,
mainFile,
moduleFormat,
srcFiles,
};
};
const bundler = { bundle, getSrcFiles };
export default bundler;