From 2a7de899c5123d65313be417137c34aa0c388427 Mon Sep 17 00:00:00 2001 From: Bob Ippolito Date: Wed, 27 Mar 2024 18:22:52 -0700 Subject: [PATCH] Node fork module with async await --- scripts/build.js | 55 +++++++++++++++++++++++++++------------- scripts/updateVersion.js | 22 +++++++++++----- 2 files changed, 54 insertions(+), 23 deletions(-) diff --git a/scripts/build.js b/scripts/build.js index f3750e0841f..f701658b58b 100644 --- a/scripts/build.js +++ b/scripts/build.js @@ -612,17 +612,29 @@ async function moveTSDeclarationFilesIntoDist(packageName, outputPath) { await fs.copy(`./.ts-temp/${packageName}/src`, outputPath); } -function buildForkModule(outputPath, outputFileName, format, exports) { +function forkModuleContent( + {devFileName, exports, outputFileName, prodFileName}, + target, +) { const lines = [getComment()]; - const extension = getExtension(format); - const devFileName = `./${outputFileName}.dev${extension}`; - const prodFileName = `./${outputFileName}.prod${extension}`; - if (format === 'esm') { + if (target === 'cjs') { lines.push( - `import * as modDev from '${devFileName}';`, - `import * as modProd from '${prodFileName}';`, - `const mod = process.env.NODE_ENV === 'development' ? modDev : modProd;`, + `'use strict'`, + `const ${outputFileName} = process.env.NODE_ENV === 'development' ? require('${devFileName}') : require('${prodFileName}');`, + `module.exports = ${outputFileName};`, ); + } else { + if (target === 'esm') { + lines.push( + `import * as modDev from '${devFileName}';`, + `import * as modProd from '${prodFileName}';`, + `const mod = process.env.NODE_ENV === 'development' ? modDev : modProd;`, + ); + } else if (target === 'node') { + lines.push( + `const mod = await (process.env.NODE_ENV === 'development' ? import('${devFileName}') : import('${prodFileName}'));`, + ); + } for (const name of exports) { lines.push( name === 'default' @@ -630,18 +642,27 @@ function buildForkModule(outputPath, outputFileName, format, exports) { : `export const ${name} = mod.${name};`, ); } - } else { - lines.push( - `'use strict'`, - `const ${outputFileName} = process.env.NODE_ENV === 'development' ? require('${devFileName}') : require('${prodFileName}');`, - `module.exports = ${outputFileName};`, - ); } - const fileContent = lines.join('\n'); + return lines.join('\n'); +} + +function buildForkModules(outputPath, outputFileName, format, exports) { + const extension = getExtension(format); + const devFileName = `./${outputFileName}.dev${extension}`; + const prodFileName = `./${outputFileName}.prod${extension}`; + const opts = {devFileName, exports, outputFileName, prodFileName}; fs.outputFileSync( path.resolve(path.join(`${outputPath}${outputFileName}${extension}`)), - fileContent, + forkModuleContent(opts, format), ); + if (format === 'esm') { + fs.outputFileSync( + path.resolve( + path.join(`${outputPath}${outputFileName}.node${extension}`), + ), + forkModuleContent(opts, 'node'), + ); + } } async function buildAll() { @@ -693,7 +714,7 @@ async function buildAll() { false, format, ); - buildForkModule(outputPath, outputFileName, format, exports); + buildForkModules(outputPath, outputFileName, format, exports); } } } diff --git a/scripts/updateVersion.js b/scripts/updateVersion.js index ff7b6c02d1e..087c3ee5572 100644 --- a/scripts/updateVersion.js +++ b/scripts/updateVersion.js @@ -58,15 +58,22 @@ function withEsmExtension(fileName) { return fileName.replace(/\.js$/, '.mjs'); } -function exportEntry(file) { +function withNodeEsmExtension(fileName) { + return fileName.replace(/\.js$/, '.node.mjs'); +} + +function exportEntry(file, types) { + // Bundlers such as webpack require 'types' to be first and 'default' to be + // last per #5731. Keys are in descending priority order. return { + /* eslint-disable sort-keys-fix/sort-keys-fix */ import: { - types: `./${file.replace(/\.js$/, '.d.ts')}`, - // webpack requires default to be the last entry per #5731 - // eslint-disable-next-line sort-keys-fix/sort-keys-fix + types: `./${types}`, + node: `./${withNodeEsmExtension(file)}`, default: `./${withEsmExtension(file)}`, }, - require: `./${file}`, + require: {types: `./${types}`, default: `./${file}`}, + /* eslint-enable sort-keys-fix/sort-keys-fix */ }; } @@ -76,11 +83,14 @@ function updateModule(packageJSON, pkg) { } if (packageJSON.main) { packageJSON.module = withEsmExtension(packageJSON.main); + packageJSON.exports = { + '.': exportEntry(packageJSON.main, packageJSON.types || 'index.d.ts'), + }; } else if (fs.existsSync(`./packages/${pkg}/dist`)) { const exports = {}; for (const file of fs.readdirSync(`./packages/${pkg}/dist`)) { if (/^[^.]+\.js$/.test(file)) { - const entry = exportEntry(file); + const entry = exportEntry(file, file.replace(/\.js$/, '.d.ts')); // support for import "@lexical/react/LexicalComposer" exports[`./${file.replace(/\.js$/, '')}`] = entry; // support for import "@lexical/react/LexicalComposer.js"