Skip to content

Commit

Permalink
Add modulesWithSideEffectsInSrcFiles to allow esm in srcFiles
Browse files Browse the repository at this point in the history
  • Loading branch information
HolgerJeromin committed Jan 3, 2025
1 parent 4308a48 commit 07370ae
Show file tree
Hide file tree
Showing 10 changed files with 69 additions and 3 deletions.
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
2 changes: 2 additions & 0 deletions lib/examples/default_esm_config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
9 changes: 7 additions & 2 deletions lib/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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) {
Expand Down
10 changes: 10 additions & 0 deletions lib/types.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
*/
/**
* <p>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
Expand Down
2 changes: 2 additions & 0 deletions run.html.ejs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@
<% userJsFiles.forEach(function(jsFile) { %>
<% if (jsFile.endsWith(esmFilenameExtension)) { %>
<script src="<%= jsFile %>" type="module"></script>
<% } else if (modulesWithSideEffectsInSrcFiles) { %>
<script src="<%= jsFile %>" type="text/javascript" defer></script>
<% } else { %>
<script src="<%= jsFile %>" type="text/javascript"></script>
<% } %>
Expand Down
4 changes: 4 additions & 0 deletions spec/fixtures/modulesWithSideEffectsInSrcFiles/spec/aSpec.js
Original file line number Diff line number Diff line change
@@ -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);
});
Original file line number Diff line number Diff line change
@@ -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"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
window._moduleWithSyncSideEffectLoaded = true;
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
if(window._moduleWithSyncSideEffectLoaded) {
window._scriptSyncSuccess = true;
}else{
window._scriptSyncSuccess = false;
}
18 changes: 18 additions & 0 deletions spec/modulesWithSideEffectsInSrcFilesSpec.js
Original file line number Diff line number Diff line change
@@ -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
);
});

0 comments on commit 07370ae

Please sign in to comment.