From e49b3c5796160edf7b69864f794480580f810fce Mon Sep 17 00:00:00 2001 From: Jonathan Kolberg Date: Sat, 4 Jun 2022 10:12:52 +0200 Subject: [PATCH 1/2] feat(node): allow executing esm compiled scripts --- e2e/node/src/node.test.ts | 41 +++++++++++++++++++ .../node/node-with-require-overrides.ts | 4 +- 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/e2e/node/src/node.test.ts b/e2e/node/src/node.test.ts index 609d7031d5495..d0cfbf504a47d 100644 --- a/e2e/node/src/node.test.ts +++ b/e2e/node/src/node.test.ts @@ -21,6 +21,7 @@ import { tmpProjPath, uniq, updateFile, + updateJson, updateProjectConfig, } from '@nx/e2e/utils'; import { exec, execSync } from 'child_process'; @@ -230,6 +231,46 @@ describe('Node Applications', () => { expect(err).toBeFalsy(); } }, 120000); + + it('should be able to run es module applications', async () => { + const esmapp = uniq('esmapp'); + + runCLI(`generate @nrwl/node:app ${esmapp} --linter=eslint`); + updateJson(`apps/${esmapp}/tsconfig.app.json`, (config) => { + config.module = 'esnext'; + config.target = 'es2020'; + return config; + }); + updateProjectConfig(esmapp, (config) => { + config.targets.build.executor = '@nrwl/node:webpack'; + config.targets.build.options.outputFileName = 'main.mjs'; + config.targets.build.options.webpackConfig = `apps/${esmapp}/webpack.config.js`; + config.targets.serve.executor = '@nrwl/node:node'; + config.targets.serve.options.watch = false; + return config; + }); + updateFile( + `apps/${esmapp}/webpack.config.js`, + `module.exports = (config, context) => ({ + ...config, + experiments: { + ...config.experiments, + outputModule: true, + topLevelAwait: true, + }, + output: { + path: config.output.path, + chunkFormat: 'module', + library: { + type: 'module', + }, + }, + })` + ); + await runCLIAsync(`build ${esmapp}`); + const { stdout } = await runCLIAsync(`serve ${esmapp}`); + expect(stdout).toBe('Hello World!'); + }, 300000); }); describe('Build Node apps', () => { diff --git a/packages/js/src/executors/node/node-with-require-overrides.ts b/packages/js/src/executors/node/node-with-require-overrides.ts index 6d152d5adacb7..f8583422c609f 100644 --- a/packages/js/src/executors/node/node-with-require-overrides.ts +++ b/packages/js/src/executors/node/node-with-require-overrides.ts @@ -1,6 +1,8 @@ const Module = require('module'); const originalLoader = Module._load; +const dynamicImport = new Function('specifier', 'return import(specifier)'); + const mappings = JSON.parse(process.env.NX_MAPPINGS); const keys = Object.keys(mappings); const fileToRun = process.env.NX_FILE_TO_RUN; @@ -17,4 +19,4 @@ Module._load = function (request, parent) { } }; -require(fileToRun); +dynamicImport(fileToRun); From 92aa9095ab68891462ac09e8fd3a7c14d523dd69 Mon Sep 17 00:00:00 2001 From: Jonathan Kolberg Date: Sat, 4 Jun 2022 10:12:52 +0200 Subject: [PATCH 2/2] feat(node): allow executing esm compiled scripts --- e2e/node/src/node.test.ts | 48 ++++++++++++++++++++------------------- 1 file changed, 25 insertions(+), 23 deletions(-) diff --git a/e2e/node/src/node.test.ts b/e2e/node/src/node.test.ts index d0cfbf504a47d..e8ed0ee3fd8fb 100644 --- a/e2e/node/src/node.test.ts +++ b/e2e/node/src/node.test.ts @@ -232,44 +232,46 @@ describe('Node Applications', () => { } }, 120000); - it('should be able to run es module applications', async () => { + it('should be able to run ESM applications', async () => { const esmapp = uniq('esmapp'); - runCLI(`generate @nrwl/node:app ${esmapp} --linter=eslint`); + runCLI( + `generate @nrwl/node:app ${esmapp} --linter=eslint --framework=none --bundler=webpack` + ); updateJson(`apps/${esmapp}/tsconfig.app.json`, (config) => { config.module = 'esnext'; config.target = 'es2020'; return config; }); updateProjectConfig(esmapp, (config) => { - config.targets.build.executor = '@nrwl/node:webpack'; config.targets.build.options.outputFileName = 'main.mjs'; - config.targets.build.options.webpackConfig = `apps/${esmapp}/webpack.config.js`; - config.targets.serve.executor = '@nrwl/node:node'; - config.targets.serve.options.watch = false; + config.targets.build.options.assets = []; return config; }); updateFile( `apps/${esmapp}/webpack.config.js`, - `module.exports = (config, context) => ({ - ...config, - experiments: { - ...config.experiments, - outputModule: true, - topLevelAwait: true, - }, - output: { - path: config.output.path, - chunkFormat: 'module', - library: { - type: 'module', - }, - }, - })` + ` + const { composePlugins, withNx } = require('@nx/webpack'); + module.exports = composePlugins(withNx(), (config) => { + config.experiments = { + ...config.experiments, + outputModule: true, + topLevelAwait: true, + }; + config.output = { + path: config.output.path, + chunkFormat: 'module', + library: { type: 'module' } + } + return config; + }); + ` ); await runCLIAsync(`build ${esmapp}`); - const { stdout } = await runCLIAsync(`serve ${esmapp}`); - expect(stdout).toBe('Hello World!'); + const p = await runCommandUntil(`serve ${esmapp}`, (output) => { + return output.includes('Hello World'); + }); + p.kill(); }, 300000); });