14

I'm pretty new to Webpack, but can't figure out why my ProvidePlugin call is not working as expected.

I have the following file:

App.js

var App = function() {
    getSomething: function(size) {}
}();

module.exports = App;

I want this 'App' variable to be globally accessible because other files use it like this:

Layout.js

var Layout = function () {
    App.getSomething('md');
}();

webpack.config.js

In webpack.config.js I have the following line:

new webpack.ProvidePlugin({ App: 'app' })

This is my entry:

entry: {
    'app': './angularApp/metronicapp.ts',
}

metronicapp.ts

import './metronic/global/scripts/app';

Where app is my app.js which is displayed above.

I get the following error in the browser: Cannot find module "app"

And when I compile webpack in the console: Module not found: Error: Can't resolve 'app'

I can't figure what I'm missing. Is my app.js not in the correct format? Why is App still not available globally?

Dennis de Laat
  • 513
  • 1
  • 5
  • 10
  • In your metronicapp.ts you are not importing the app. In App JS you could try changing the module.export to export default App. Or in the metronicapp.ts change the import to "import App from './metronic/global/scripts/app' " I'm new to this also, but that is what I would try. – Jason Allshorn Dec 07 '17 at 19:04

1 Answers1

12

webpack.config.js

ProvidePlugin needs the path to your global module App.js.

const path = require('path');
...
plugins: [
  new webpack.ProvidePlugin({
    App: path.resolve(__dirname, './path_to_App.js')
  })
]

global.d.ts

For Typescript not to complain about undefined constructs create global.d.ts

declare var App: any;

metronicapp.ts

No need to import ./metronic/global/scripts/app inside metronicapp.ts, webpack will resolve App on build.

App.getSomething('foo');

Layout.js

var Layout = function() {
  App.getSomething('md');
}();
arpl
  • 3,505
  • 3
  • 18
  • 16
  • 1
    Thanks for your answer! All I had to add to make it work were the following lines: module: { rules: [ { test: require.resolve(path.join(ROOT, 'angularApp/metronic/global/scripts/metronic-app.js')), use: ['exports-loader?App'] }] } – Dennis de Laat Dec 09 '17 at 19:00
  • Pointing to the path fails catastrophically for me. – Slbox Apr 17 '19 at 18:53