Aleksandar Vasić
Aleksandar Vasić

Reputation: 593

Webpack access class from other class

I'm trying to access class functions from other class which are webpacked. I have:

var App = function () {
    getResponsiveBreakpoint: function(size) {
        var sizes = {
            'xs' : 480,     // extra small
            'sm' : 768,     // small
            'md' : 992,     // medium
            'lg' : 1200     // large
        };

        return sizes[size] ? sizes[size] : 0;
    }
}

and I want to access this function from:

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

these classes are webpacked, here's config:

    var path                  = require('path'),
        webpack               = require('webpack'),
        ExtractTextPlugin     = require("extract-text-webpack-plugin"),
        autoprefixer          = require('autoprefixer'),
        precss                = require('precss'),
        ProvidePlugin         = require('webpack/lib/ProvidePlugin'),
        jsPath                = './js',
        jsLayoutPath          = './js/layout',
        cssPath               = './css',
        cssLayoutPath         = './css/layout',
        cssThemesPath         = './css/layout/themes';

    module.exports = {
        entry: {
            login: [jsPath + '/login.js', cssPath + '/login.css'],
            layout: [jsLayoutPath + '/layout.js', cssLayoutPath + '/layout.css'],
            custom: cssLayoutPath + '/custom.css',
            vendor: [
                cssPath + '/bootstrap.css',
                cssPath + '/bootstrap-switch.css',
                cssPath + '/font-awesome.css',
                cssPath + '/datatables.bootstrap.css',
                cssPath + '/datatables.css',
                cssPath + '/datatables.font-awesome.css',
                cssPath + '/select2.css',
                cssPath + '/select2-bootstrap.css',
                cssPath + '/components.css',
                cssPath + '/plugins.css',
                cssPath + '/daterangepicker.css',
                cssPath + '/uniform.default.css',
                jsPath + '/jquery.js',
                jsPath + '/jquery.blockUI.js',
                jsPath + '/bootstrap.js',
                jsPath + '/bootstrap-hover-dropdown.js',
                jsPath + '/bootstrap-switch.js',
                jsPath + '/select2.full.js',
                jsPath + '/jquery.waypoints.min.js',
                jsPath + '/jquery.slimscroll.js',
                jsPath + '/jquery.counterup.js',
                jsPath + '/jquery.uniform.js',
                jsPath + '/jquery.validate.js',
                jsPath + '/jquery.form.js',
                jsPath + '/additional-methods.js',
                jsPath + '/datatables.js',
                jsPath + '/datatables.bootstrap.js',
                jsPath + '/app.js'
            ],
            respond: jsPath + '/respond.src.js',
            excanvas: jsPath + '/excanvas.js'
        },
        output:  {
            path: __dirname + "/../../web/assets/js/", publicPath: '/assets/js/', filename: "[name].js"
        },
        module:  {
            loaders: [
                {
                    test: /\.css$/,
                    exclude: /node_modules/,
                    loader: ExtractTextPlugin.extract("style-loader", "css-raw-loader!postcss-loader")
                },
                { test: /jquery\.js$/, loader: 'expose?$' },
                { test: /jquery\.js$/, loader: 'expose?jQuery' },
                { test: /datatables\.js$/, loader: 'expose?DataTable' },
                { test: /jquery\.form\.js$/, loader: "imports?define=>false" },
                {
                    test:    /\.js(x)?$/,
                    exclude: /node_modules/,
                    loader:  'babel',
                    query:   {
                        plugins:   [
                            "transform-class-properties"
                        ],
                        "presets": [
                            "stage-0",
                            "es2015",
                            "react"
                        ],
                        compact: false
                    }
                },
            ],
            postcss: function() {
                return [autoprefixer, precss];
            }
        },
        plugins: [
            new webpack.ProvidePlugin({
                $: "jquery",
                jQuery: "jquery",
                "window.jQuery": "jquery",
                "DataTable": "datatables.net"
            }),
            new webpack.optimize.UglifyJsPlugin({
                compress: { warnings: false },
            }),
            new webpack.optimize.CommonsChunkPlugin("commons", "../js/commons.min.js"),
            new ExtractTextPlugin("../css/[name].min.css", {
                allChunks: true
            }),
        ]
    };

How can I achieve this? I tried with expose module, but never succeeded. Thanks!

Upvotes: 1

Views: 842

Answers (1)

Grgur
Grgur

Reputation: 7382

I'll rewrite as an answer. There seem to be many things you can do to improve on as part of both JavaScript as Webpack config, but i'll try to focus on the question.

  1. Use modules

    import App from '../app.js';
    
    var Layout = function() {
        var resBreakpointMd = App.getResponsiveBreakpoint('md');
    }
    

    and

    var App = {
        getResponsiveBreakpoint: function(size) {
            var sizes = {
                'xs' : 480,     // extra small
                'sm' : 768,     // small
                'md' : 992,     // medium
                'lg' : 1200     // large
            };
            return sizes[size] ? sizes[size] : 0;
        }
      }
    
    export default App;
    
  2. You defined getResponsiveBreakpoint as a member of a function so it's lexically scoped inside. That way it's not accessible from the outside. The easiest thing was to convert it to object as I did in code above

Depending on what you want to achieve, you could also make it a static member of a function as such:

var App = function () {
    // some logic here  
}

App.getResponsiveBreakpoint: function(size) {
   var sizes = {
       'xs' : 480,     // extra small
       'sm' : 768,     // small
       'md' : 992,     // medium
       'lg' : 1200     // large
    };
    return sizes[size] ? sizes[size] : 0;
}

export default App;

I hope that helps for now.

Upvotes: 1

Related Questions