javascriptnode.jsecmascript-6browserifybabelify

Cannot call functions after running browserify


I have a an es6 JS class below which I am running through browserify to output in es5. Below is my es6 JS class:

import $j from "jquery";
import BaseComponent from './Components/base-component';

class QuestionnaireView extends BaseComponent {

constructor() {

    super();

    this.defaultOptions = {
        questionId : '#questionId',
        responseId : '#responseId',
        answerId : '#answerId',
        questionTextId : '#questionTextId'
    };

    this.state = {
    };
}

initChildren() {
}

addListeners() {
}

collectQuestions() {
    var questionAndAnswersDict = [];
    var answersAndWeightingsDict = [];
    
    $j(this.options.questionId).each(function () {
        var questionText = $j(this).find("input")[0].value;
        $j(this.options.answerId).each(function () {
            var answerText = $j(this).find("input")[0].value;
            var weighting = $j(this).find("input")[1].value;
            answersAndWeightingsDict.push({
                key: answerText,
                value: weighting
            });
        });
        questionAndAnswersDict.push({
            key: questionText,
            value: answersAndWeightingsDict
        });
    });
}

collectResponses() {
    var responsesDict = [];
    var weightingDict = [];

    $j(this.options.responseId).each(function () {
        var minWeighting = $j(this).find("input")[0].value;
        var maxWeighting = $j(this).find("input")[1].value;
        var responseText = $j(this).find("input")[2].value;
        weightingDict.push({
            key: minWeighting,
            value: maxWeighting
        });
        responsesDict.push({
            key: responseText,
            value: weightingDict
        });
    });
}
}

export default () => { return new QuestionnaireView(); };

And here is the browserify command I am running:

browserify Scripts/questionnaire-view.js -o wwwroot/js/questionnaire-view.js

I have also tried

browserify Scripts/questionnaire-view.js -o wwwroot/js/questionnaire-view.js -t [ babelify --presets [ @babel/preset-env @babel/preset-react ] --plugins [ @babel/plugin-transform-modules-commonjs ] ]

The output JS file looks okay and does not throw any errors in dev tools but when I go to call a function I get the following:

Error: Microsoft.JSInterop.JSException: Could not find 'collectQuestions' ('collectQuestions' was undefined).
Error: Could not find 'collectQuestions' ('collectQuestions' was undefined).
at http://localhost:41131/_framework/blazor.server.js:1:288
at Array.forEach (<anonymous>)
at r.findFunction (http://localhost:41131/_framework/blazor.server.js:1:256)
at v (http://localhost:41131/_framework/blazor.server.js:1:1882)
at http://localhost:41131/_framework/blazor.server.js:1:2662
at new Promise (<anonymous>)
at et.beginInvokeJSFromDotNet (http://localhost:41131/_framework/blazor.server.js:1:2643)
at http://localhost:41131/_framework/blazor.server.js:1:62750
at Array.forEach (<anonymous>)
at et._invokeClientMethod (http://localhost:41131/_framework/blazor.server.js:1:62736)

Any help is greatly appreciated :)


Solution

  • I ended up using webpack with babel loader:

    var devJSConfig = Object.assign({}, config, {
    mode: 'development',
    entry: [
        path.resolve(__dirname, './Scripts/Components/base-component.js'),
        path.resolve(__dirname, './Scripts/address-view.js'),
        path.resolve(__dirname, './Scripts/customer-view.js'),
        path.resolve(__dirname, './Scripts/questionnaire-view.js')
    ],
    output: {
        path: path.resolve(__dirname, 'wwwroot/js'),
        filename: "[name].js"
    },
    module: {
        rules: [
            {
                test: /\.(js|jsx)$/,
                exclude: '/node_modules/',
                use: [
                    {
                        loader: 'babel-loader',
                        options: {
                            presets: [
                                "@babel/preset-env"
                            ]
                        }
                    }
                ]
            }
        ]
    }
    

    });

    In my _Host.cshtml I had the script tag type attribute for my js files set to 'text/javascript' when it needs to be 'module'. I was also linking the individual script files but only needed to reference the bundle js which was produced using the above.

    Lastly in my script I had to expose the js class to the Window like so (place this at the end of your js class):

    window['QuestionnaireView'] = new QuestionnaireView();
    

    I could then call js functions in my Blazor component class using:

    var test = await jSRuntime.InvokeAsync<Object>("QuestionnaireView.collectQuestions");