According to the browserify-shim docs, you can specify which globals browserify-shim needs to expose from your legacy modules by using the following syntax in your package.json
:
{
"browserify-shim": {
"legacyModule": "myVar"
}
}
I want the legacy module to be accessible via require('legacyModule')
and window.myVar
.
From my experience, if the non-commonjs module I am trying to shim uses window.myVar = x
or just myVar = x
, the module is exposed globally and is available via require()
as expected.
However, when the legacy module uses var myVar = x
, that is what causes the problem as the module is then only accessible via require('legacyModule')
and not via window.myVar
.
The browserify-shim documentation states that:
Additionally, it handles the following real-world edge cases:
- Modules that just declare a
var foo = ...
on the script level and assume it gets attached to thewindow
object. Since the only way they will ever be run is in the global context — "ahem, ... NO?!"
As @EvanDull suggested, I believe browserify-shim may not actually be designed to work that way and the documentation lacks clarity on that. In the debugging that I did, it did not appear that browserify-shim is designed to set a global variable when it "handles" var foo = ...
. Where the documentation says it handles that, I believe it means it handles it not already being set on the global object and it will still export the value of that variable for CommonJS, e.g. var foo = ...; module.exports = foo;
, so that it can be require()
'd. Whereas you would like it to do var foo = ...; window.foo = module.exports = foo;
And of course since it doesn't do that and browserify wraps the legacy code in a function, var foo
creates a local variable only.
There are a number of possible workarounds you may be able to use for now:
If you don't mind editing the legacy scripts you can just delete the var
and that should take care of it.
You could pull the legacy scripts in via separate <script>
tags instead of bundling them.
You could use a browserify transform to add an additional assignment global.myVar = myVar
to the end of the legacy script. That would require tailoring the transform for each specific script you need it for.
You could make the first file in your bundle a script that does something like:
[['legacyModule, 'myVar'], ...].forEach(function (mod) {
window[mod[1]] = require(mod[0]);
});