Closed npetruzzelli closed 3 years ago
In what scenario would you not want window
to be the global object while using karma-webpack?
First I'd like to apologize, in getting more information to answer your question, I have learned that the problem is in Webpack, not karma-webpack.
Second, I'd like to answer your question anyway for the sake of anyone else who finds their way to this issue.
From Webpack's documentation:
output.globalObject
string = 'window'
When targeting a library, especially when
libraryTarget
is'umd'
, this option indicates what global object will be used to mount the library. To make UMD build available on both browsers and Node.js, setoutput.globalObject
option to'this'
. Defaults toself
for Web-like targets.For example:
webpack.config.js
module.exports = { // ... output: { library: 'myLib', libraryTarget: 'umd', filename: 'myLib.js', globalObject: 'this', }, };
Aside from this, I believe there there are 2 reasonable reasons:
The fact that it doesn't work is surprising. Projects have every reason to believe that their configuration is valid when using this value for this option. Explicitly setting libraryTarget: "umd"
doesn't help.
Third, I would like to share my findings.
The runtime code in question:
C:/Users/%USERNAME%/AppData/Local/Temp/_karma_webpack_645953/runtime.js
Which effectively breaks down to:
(function(){
"use strict";
!function(){ console.log(this) }()
})()
;
In strict mode, however, if the value of
this
is not set when entering an execution context, it remains asundefined
In Webpack v4, the bootstrap code does not include "use strict"
.
webpack/lib/MainTemplate.js#L154
source.add("/******/ (function(modules) { // webpackBootstrap\n");
In Webpack 5, there is an allStrict
variable which I would need to dig into to understand beyond reasonable assumptions.
webpack/lib/javascript/JavascriptModulesPlugin.js#L548-L569
const allStrict = allModules.every(m => m.buildInfo.strict);
let inlinedModules;
if (bootstrap.allowInlineStartup) {
inlinedModules = new Set(chunkGraph.getChunkEntryModulesIterable(chunk));
}
let source = new ConcatSource();
let prefix;
if (iife) {
if (runtimeTemplate.supportsArrowFunction()) {
source.add("/******/ (() => { // webpackBootstrap\n");
} else {
source.add("/******/ (function() { // webpackBootstrap\n");
}
prefix = "/******/ \t";
} else {
prefix = "/******/ ";
}
if (allStrict) {
source.add(prefix + '"use strict";\n');
}
So the problem lies in the webpack
code setting strict mode, so this
is no longer a reference to the window object. If there is a new option in Webpack 5 that allows us to influence allStrict
then the answer may lie there. Otherwise this may be an issue that I'll need to ask the Webpack repository about.
As an aside, there is nothing explicitly telling Webpack users what all valid values are for output.globalObject
. Since it looks like code in Webpack ends up being:
`${output.globalObject}[${globalPropertyName}] = ${javascriptCodeAsString}`
It is reasonable to assume the valid values are:
"this"
"globalThis"
- you should only use this if all your target environments support it"self"
- web browsers, web workers, jsdom in Node"window"
- web browsers"global"
- NodeOther JavaScript environments may have other global objects, but that probably won't be relevant to many people who find their way to this issue.
Windows 10
14.2.0
6.14.11
(yarn:1.22.5
)5.23.0
5.0.0
Expected Behavior
Successful build and test suite execution
Actual Behavior
The test suite isn't able to run at all.
NOTE: if
globalObject
isundefined
,"window"
, or"self"
, then the build is successful."this"
is a valid, documented value, but results in an error.This problem does not seem to happen when using
karma-webpack
withwebpack
4.x.Changing the
globalObject
option does not seem to change the resulting code when usingwebpack-cli
to build a bundle file.Code
Toggle Module Details
**Babel Modules:** - `@babel/core` - `@babel/preset-env` **Webpack Modules** - `babel-loader` - `webpack` **Karma Modules** - `karma` - `karma-chrome-launcher` - `karma-ie-launcher` - `karma-jasmine` - `karma-webpack`How Do We Reproduce?
yarn test --singleRun
ornpm test -- --singleRun