Skip to content

Understanding Global

David Graham edited this page Jun 26, 2018 · 5 revisions

Before advancing on in this tutorial, it's important to understand the different ways we can use code globally in Webpack...

Webpack Evaluates Modules Only Once

Webpack evaluates modules only once, so your instance remains global and carries changes through from module to module. So if you create something like a globals.js and export an object of all your globals then you can import './globals' and read/write to these globals. You can import into one module, make changes to the object from a function and import into another module and read those changes in a function. Also remember the order things happen. Webpack will first take all the imports and load them up in order starting in your entry point main.js. Then it will execute main.js. So where you read/write to globals is important. Is it from the root scope of a module or in a function called later?

Note: If you want the instance to be new each time, then use an ES6 class. Traditionally in JS you would capitalize classes (as opposed to the lowercase for objects) like import FooBar from './foo-bar' // <-- Usage: myFooBar = new FooBar()

ProvidePlugin

Here's how you can do it using Webpack's ProvidePlugin ( which makes a module available as a variable in every module and only those modules where you actually use it). This is useful when you don't want to keep typing import Bar from 'foo' again and again. Or you can bring in a package like jQuery or lodash as global here.

Create any module, for example, a global set of utilities would be handy (module must be in Nodejs module.exports format):

utils.js

module.exports = {

  sayHello () {
    alert("hello")
  }
}

First alias the module:

// ...

resolve: {
  extensions: ['.js', '.vue', '.json'],
  alias: {
    '@': resolve('src'),
    'utils': path.resolve(__dirname, '../utils/utils.js')
  },
  symlinks: false
},

Then add the ProvidePlugin to your plugins array in both dev and prod:

webpack.dev.config.js webpack.prod.config.js

plugins: [
  
  // ...

  new webpack.ProvidePlugin({
    'utils': 'utils'
  })
]

Don't forget to tell the linter about this global:

module.exports = {

  // ...

  globals: {
    'utils': true
  },

Now just call utils.sayHello() in any js file and it should work. Make sure you restart your dev-server if you are using that with Webpack.

Note: Don't forget to tell your linter about the global, so it won't complain. See section on ESLint.

DefinePlugin

If you just want to use const with string values for your globals, then you can use Webpack's DefinePlugin. Add this plugin to your list of Webpack plugins:

new webpack.DefinePlugin({
  PRODUCTION: JSON.stringify(true),
  VERSION: JSON.stringify("5fa3b9"),
  BROWSER_SUPPORTS_HTML5: true,
  TWO: "1+1",
  "typeof window": JSON.stringify("object")
})

Use it like:

console.log("Running App version " + VERSION);
if(!BROWSER_SUPPORTS_HTML5) require("html5shiv");

The Global Window Object

Since this example app is focused on running from a browser environment, we can also use the browser's global Window object:

window.Promise = Bluebird

You could also use Node's global object which Webpack will automatically convert to window if your project is targeted for web (default):

global.Promise = Bluebird

Clone this wiki locally