From 07370aefac828273125d1efeea28553231e44f3e Mon Sep 17 00:00:00 2001 From: Holger Jeromin Date: Fri, 22 Nov 2024 16:55:46 +0100 Subject: [PATCH] Add modulesWithSideEffectsInSrcFiles to allow esm in srcFiles --- README.md | 5 ++++- lib/examples/default_esm_config.mjs | 2 ++ lib/server.js | 9 +++++++-- lib/types.js | 10 ++++++++++ run.html.ejs | 2 ++ .../spec/aSpec.js | 4 ++++ .../spec/support/jasmine-browser.js | 16 ++++++++++++++++ .../src/moduleWithSideEffects.mjs | 1 + .../src/scriptNeedsSideEffect.js | 5 +++++ spec/modulesWithSideEffectsInSrcFilesSpec.js | 18 ++++++++++++++++++ 10 files changed, 69 insertions(+), 3 deletions(-) create mode 100644 spec/fixtures/modulesWithSideEffectsInSrcFiles/spec/aSpec.js create mode 100644 spec/fixtures/modulesWithSideEffectsInSrcFiles/spec/support/jasmine-browser.js create mode 100644 spec/fixtures/modulesWithSideEffectsInSrcFiles/src/moduleWithSideEffects.mjs create mode 100644 spec/fixtures/modulesWithSideEffectsInSrcFiles/src/scriptNeedsSideEffect.js create mode 100644 spec/modulesWithSideEffectsInSrcFilesSpec.js diff --git a/README.md b/README.md index 2dc757c..f41e9d6 100644 --- a/README.md +++ b/README.md @@ -156,8 +156,11 @@ config field to something that's high enough up to include both spec and source files, and set `srcFiles` to `[]`. You can autogenerate such a configuration by running `npx jasmine-browser-runner init --esm`. +If you want to load ES module source directly on load instead of loading it from +the corresponding spec, set the `modulesWithSideEffectsInSrcFiles` config property to `true`. + If you have specs or helper files that use top-level await, set the -`enableTopLevelAwait` config property is set to `true`. +`enableTopLevelAwait` config property to `true`. [Import maps](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script/type/importmap) are also supported: diff --git a/lib/examples/default_esm_config.mjs b/lib/examples/default_esm_config.mjs index 68ba86e..9e5c86d 100644 --- a/lib/examples/default_esm_config.mjs +++ b/lib/examples/default_esm_config.mjs @@ -11,6 +11,8 @@ export default { "spec/helpers/**/*.?(m)js" ], esmFilenameExtension: ".mjs", + // Set to true if you need to load module src files instead of loading via the spec files. + modulesWithSideEffectsInSrcFiles: false, // Allows the use of top-level await in src/spec/helper files. This is off by // default because it makes files load more slowly. enableTopLevelAwait: false, diff --git a/lib/server.js b/lib/server.js index 925771a..2b14f01 100644 --- a/lib/server.js +++ b/lib/server.js @@ -82,8 +82,11 @@ class Server { this.options.srcFiles, '/__src__' ).filter(url => { - // Exclude ES modules. These will be loaded by other ES modules. - return !url.endsWith(this.options.esmFilenameExtension); + // Exclude ES modules by default. These will be loaded by other ES modules. + return ( + this.options.modulesWithSideEffectsInSrcFiles || + !url.endsWith(this.options.esmFilenameExtension) + ); }); const helperUrls = this.getUrls( this.options.specDir, @@ -191,6 +194,8 @@ class Server { esmFilenameExtension: self.options.esmFilenameExtension, importMap: self.importMap(), enableTopLevelAwait: self.options.enableTopLevelAwait || false, + modulesWithSideEffectsInSrcFiles: + self.options.modulesWithSideEffectsInSrcFiles || false, }) ); } catch (error) { diff --git a/lib/types.js b/lib/types.js index 391960d..b12e19a 100644 --- a/lib/types.js +++ b/lib/types.js @@ -153,6 +153,16 @@ * @type boolean | undefined * @default false */ +/** + * If set to true jasmine loads also ES Modules which are included in SrcFiles. + * This option is off by default because in most scenarios it is better to load the + * module under test from the test itself. + * But if the module has wanted side effects (like for example polyfills) you can + * interleave ES module and classic scripts in your SrcFiles. + * @name Configuration#modulesWithSideEffectsInSrcFiles + * @type boolean | undefined + * @default false + */ /** *

An optional map from paths to Express application middleware to mount on * those paths. This can be used to serve static files, proxy requests to diff --git a/run.html.ejs b/run.html.ejs index d77f550..7405a26 100644 --- a/run.html.ejs +++ b/run.html.ejs @@ -30,6 +30,8 @@ <% userJsFiles.forEach(function(jsFile) { %> <% if (jsFile.endsWith(esmFilenameExtension)) { %> + <% } else if (modulesWithSideEffectsInSrcFiles) { %> + <% } else { %> <% } %> diff --git a/spec/fixtures/modulesWithSideEffectsInSrcFiles/spec/aSpec.js b/spec/fixtures/modulesWithSideEffectsInSrcFiles/spec/aSpec.js new file mode 100644 index 0000000..34b1c36 --- /dev/null +++ b/spec/fixtures/modulesWithSideEffectsInSrcFiles/spec/aSpec.js @@ -0,0 +1,4 @@ +it('verifies that ES modules in sources are automatically loaded in the correct order', function() { + expect(window._moduleWithSyncSideEffectLoaded).withContext('window._moduleWithSyncSideEffectLoaded').toBe(true); + expect(window._scriptSyncSuccess).withContext('window._scriptSyncSuccess').toBe(true); +}); diff --git a/spec/fixtures/modulesWithSideEffectsInSrcFiles/spec/support/jasmine-browser.js b/spec/fixtures/modulesWithSideEffectsInSrcFiles/spec/support/jasmine-browser.js new file mode 100644 index 0000000..8c808fc --- /dev/null +++ b/spec/fixtures/modulesWithSideEffectsInSrcFiles/spec/support/jasmine-browser.js @@ -0,0 +1,16 @@ +module.exports = { + "srcDir": "src", + "srcFiles": [ + "moduleWithSideEffects.mjs", + "scriptNeedsSideEffect.js" + ], + "specDir": "spec", + "specFiles": [ + "aSpec.js" + ], + "random": false, + "modulesWithSideEffectsInSrcFiles": true, + "browser": { + "name": "headlessChrome" + } +} diff --git a/spec/fixtures/modulesWithSideEffectsInSrcFiles/src/moduleWithSideEffects.mjs b/spec/fixtures/modulesWithSideEffectsInSrcFiles/src/moduleWithSideEffects.mjs new file mode 100644 index 0000000..01df03e --- /dev/null +++ b/spec/fixtures/modulesWithSideEffectsInSrcFiles/src/moduleWithSideEffects.mjs @@ -0,0 +1 @@ +window._moduleWithSyncSideEffectLoaded = true; \ No newline at end of file diff --git a/spec/fixtures/modulesWithSideEffectsInSrcFiles/src/scriptNeedsSideEffect.js b/spec/fixtures/modulesWithSideEffectsInSrcFiles/src/scriptNeedsSideEffect.js new file mode 100644 index 0000000..86986dd --- /dev/null +++ b/spec/fixtures/modulesWithSideEffectsInSrcFiles/src/scriptNeedsSideEffect.js @@ -0,0 +1,5 @@ +if(window._moduleWithSyncSideEffectLoaded) { + window._scriptSyncSuccess = true; +}else{ + window._scriptSyncSuccess = false; +} diff --git a/spec/modulesWithSideEffectsInSrcFilesSpec.js b/spec/modulesWithSideEffectsInSrcFilesSpec.js new file mode 100644 index 0000000..176594d --- /dev/null +++ b/spec/modulesWithSideEffectsInSrcFilesSpec.js @@ -0,0 +1,18 @@ +const { + runJasmine, + expectSuccess, + timeoutMs, +} = require('./integrationSupport'); + +describe('ESM in Specs', function() { + it( + 'optionally loads ESM files in spec', + async function() { + const result = await runJasmine( + 'spec/fixtures/modulesWithSideEffectsInSrcFiles' + ); + expectSuccess(result, '1 spec, 0 failures'); + }, + timeoutMs + ); +});