admin管理员组

文章数量:1415684

In my web applications, I have many JS files that I include in the HTML body. They define many symbols that I can use directly in <script> elements. Now, I need to use these applications inside a quite old web engine (the traditional MS WebView, which in practice means IE11), but my JS uses a lot of (relatively) new syntax (mainly arrow functions () =>). I managed to configure Webpack and Babel to translate the code, but I lose visibility of symbols unless I explicitly add the export keyword or assign them to corresponding members of the global window object. Although it's a simple (and, I hope, harmless) code change, I would like to avoid it. Is there a way to instruct Webpack/Babel to preserve symbol visibility as it happens with plain JS scripts in HTML?

In my web applications, I have many JS files that I include in the HTML body. They define many symbols that I can use directly in <script> elements. Now, I need to use these applications inside a quite old web engine (the traditional MS WebView, which in practice means IE11), but my JS uses a lot of (relatively) new syntax (mainly arrow functions () =>). I managed to configure Webpack and Babel to translate the code, but I lose visibility of symbols unless I explicitly add the export keyword or assign them to corresponding members of the global window object. Although it's a simple (and, I hope, harmless) code change, I would like to avoid it. Is there a way to instruct Webpack/Babel to preserve symbol visibility as it happens with plain JS scripts in HTML?

Share Improve this question asked Feb 11 at 12:17 Giuseppe GuerriniGiuseppe Guerrini 4,43821 silver badges35 bronze badges 2
  • What are you using in the transpilation step as the target environment? – Pointy Commented Feb 11 at 13:46
  • In my webpack.config.js I have target: ['web', 'es5'], in babel.config.js targets: ['ie 11'],. My target is IE11 – Giuseppe Guerrini Commented Feb 11 at 17:09
Add a comment  | 

1 Answer 1

Reset to default 1

In short, not really.

I'll save you the "global variables are a bad idea" spiel and get straight to the technical aspects.

In order to define a globarl variable, you need to define it at the module level (among other requirements which I'm skipping).

However, in order to work, Webpack wraps every module in a big ol' function, which means that any declared variables are defined within a function scope, not the global scope.

For the vast majority of engineers, this behavior of Webpack is not just a side effect... it's a major reason to use a bundler in the first place.

As you've already noted, the way to sidestep this feature is to add properties to the window object, e.g. window.myGlobal =.


Now, there is actually one exception to all of this. If a module is defining a library which is intended to be "exported" as a global variable (for example, jQuery), you can use output: { library: "variableName" }.

So, taking the example straight from the linked docs:

webpack.config.js

module.exports = {
  // …
  entry: './src/index.js',
  output: {
    library: 'MyLibrary',
  },
};

src/index.js

export function hello(name) {
  console.log(`hello ${name}`);
}

index.html

<script src="https://example./path/to/my-library.js"></script>
<script>
  MyLibrary.hello('webpack');
</script>

If you have multiple modules like this, then you can return an array in your webpack.config.js:

module.exports = [{
  // …
  entry: './src/lib/oneLib.js',
  output: {
    library: '$OneLib',
  },
},{
  // …
  entry: './src/lib/twoLib.js',
  output: {
    library: '$TwoLib',
  },
}];

index.html

<script src="https://example./path/to/oneLib.js"></script>
<script src="https://example./path/to/twoLib.js"></script>
<script>
  $OneLib.foo();
  $TwoLib.bar();
</script>

If you take this approach, then you'd probably want to avoid directly importing these libraries in your other modules, as this would cause code duplication. Just use them as globals (again, like jQuery).

本文标签: javascriptPreserving original global namespace in transpiled JavaScripStack Overflow