question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

JS Minification during React Build throws off eel.init

See original GitHub issue

I’m building an app using React for the Front End after the example of @KyleKing During development everything works perfectly but upon running npm run build and even npm run build -- --profile the script is not able to parse the enclosed JS functions.

Here the code in App.js:

function show_log(msg) {
    window.AppComponent.showLog(msg)
}

window.eel.expose(show_log, 'show_log')

Here’s the minified version after running npm run build -- --profile

we.set_host("ws://localhost:8080"), window.eel.expose((function show_log(e) {
            window.AppComponent.showLog(e)
        }), "show_log");

I don’t know what else to do on the js side but I think from the Python side there are two possible solutions:

  1. Adapt eel.init to accept an array of function names to accept as default functions to be registered (and replace the assert error with a logging statement)
  2. Adapt the regex for finding the js functions → a possible alternative pattern would be: eel\.expose\(.*[;\)] to then pass into a more exhaustive isolation script I guess this would be an issue where @samuelhwilliams would need to have a say in.

Please let me know if there are specific things I can do on the JS side to avoid having to adjust the package.

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:5 (3 by maintainers)

github_iconTop GitHub Comments

1reaction
samuelhwilliamscommented, Jul 25, 2020

Hey @KyleKing - this looks good, thanks for picking it up.

I’m just going to merge some initial basic functional tests. Could you maybe add add some test cases to your PR and then I’ll give it a review. Thanks!

0reactions
KyleKingcommented, Jul 25, 2020

Got it! Below is a standalone proof of concept and I’ve created a prototype PR for feedback #365

EXPOSED_JS_FUNCTIONS = pp.ZeroOrMore(
    pp.Suppress(
        pp.SkipTo(pp.Literal('eel.expose('))
        + pp.Literal('eel.expose(')
        + pp.Optional(
            pp.Or([pp.nestedExpr(), pp.Word(pp.printables, excludeChars=',')]) + pp.Literal(',')
        )
    )
    + pp.Word(pp.printables, excludeChars=')')
    + pp.Suppress(pp.Literal(')')),
)

As an example with a couple of test cases:

import pyparsing as pp

# See EXPOSED_JS_FUNCTIONS above

TEST_CASES = [
    ('eel.expose(w,"say_hello_js")', ['"say_hello_js"']),
    ('eel.expose(function(e){console.log(e)},"show_log_alt")', ['"show_log_alt"']),
    (' \t\nwindow.eel.expose((function show_log(e) {console.log(e)}), "show_log")\n', ['"show_log"']),
    # Example minified code from https://github.com/samuelhwilliams/Eel/issues/363#issuecomment-663506276
    ("""(window.webpackJsonp=window.webpackJsonp||[]).push([[0],{15:function(e,t,o){},16:function(e,t,o){},17:function(e,t,o){"use strict";o.r(t);var n=o(0),a=o.n(n),s=o(2),c=o.n(s),r=(o(15),o(3)),i=o(4),l=o(7),p=o(5),u=o(8),m=o(6),h=o.n(m),d=(o(16),window.eel);function w(e){console.log("Hello from "+e)}d.set_host("ws://localhost:8081"),window.eel.expose(w,"say_hello_js"),window.eel.expose(function(e){console.log(e)},"show_log_alt"),window.eel.expose((function show_log(e) {console.log(e)}), "show_log"),w("Javascript World!"),d.say_hello_py("Javascript World!");var f="~",g=function(e){function t(){var e,o;Object(r.a)(this,t);for(var n=arguments.length,a=new Array(n),s=0;s<n;s++)a[s]=arguments[s];return(o=Object(l.a)(this,(e=Object(p.a)(t)).call.apply(e,[this].concat(a)))).state={message:"Click button to choose a random file from the user's system",path:f},o.pickFile=function(){d.pick_file(f)(function(e){return o.setState({message:e})})},o}return Object(u.a)(t,e),Object(i.a)(t,[{key:"render",value:function(){var e=this;return d.expand_user(f)(function(t){return e.setState({path:t})}),a.a.createElement("div",{className:"App"},a.a.createElement("header",{className:"App-header"},a.a.createElement("img",{src:h.a,className:"App-logo",alt:"logo"}),a.a.createElement("p",null,this.state.message),a.a.createElement("button",{className:"App-button",onClick:this.pickFile},"Pick Random File From `",this.state.path,"`")))}}]),t}(n.Component);Boolean("localhost"===window.location.hostname||"[::1]"===window.location.hostname||window.location.hostname.match(/^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/));c.a.render(a.a.createElement(g,null),document.getElementById("root")),"serviceWorker"in navigator&&navigator.serviceWorker.ready.then(function(e){e.unregister()})},6:function(e,t,o){e.exports=o.p+"static/media/logo.5d5d9eef.svg"},9:function(e,t,o){e.exports=o(17)}},[[9,1,2]]]);
//# sourceMappingURL=main.f500e2b1.chunk.js.map
""", ['"say_hello_js"', '"show_log_alt"', '"show_log"']),
    # Below is from: https://github.com/samuelhwilliams/Eel/blob/master/examples/05%20-%20input/web/main.html
    ("""<!DOCTYPE html>
<html>
<head>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.3/css/bootstrap.min.css" integrity="sha384-Zug+QiDoJOrZ5t4lssLdxGhVrurbmBWopoEl+M6BdEfwnCJZtKxi1KgxUyJq13dy" crossorigin="anonymous">
    <script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
    <!-- Include eel.js - note this file doesn't exist in the 'web' directory -->
    <script type="text/javascript" src="/eel.js"></script>
    <script type="text/javascript">
    $(function(){

                eel.expose(say_hello_js);               // Expose this function to Python
                function say_hello_js(x) {
                console.log("Hello from " + x);
                }
                say_hello_js("Javascript World!");
                eel.handleinput("connected!");  // Call a Python function

                $("#btn").click(function(){
                    eel.handleinput($("#inp").val());
                    $('#inp').val('');
                });
    });
    </script>
</head>

<body>
    <h1>Input Example: Enter a value and check python console</h1>
    <div>
        <input type='text' id='inp' placeholder='Write anything'>
        <input type='button' id='btn' class='btn btn-primary' value='Submit'>
    </div>
</body>
</html>""", ['say_hello_js']),
]


if __name__ == '__main__':
    for (js_code, expected_matches) in TEST_CASES:
        matches = EXPOSED_JS_FUNCTIONS.parseString(js_code).asList()
        assert matches == expected_matches, f'Expected {expected_matches} (found: {matches}) in: {js_code}'
Read more comments on GitHub >

github_iconTop Results From Across the Web

How to build a production version of React without minification?
Now, if I run npm run build I get a minified version of everything in the build folder. If I, however, run npm...
Read more >
Minifying JavaScript | JetBrains Rider Documentation
Minification or compression means removing all unnecessary characters, such as spaces, new lines, comments, without changing the functionality of the source ...
Read more >
The complete best practices for minifying CSS - LogRocket Blog
Minification alters the content of code. It reduces code file size by stripping out unwanted spaces, characters, and formatting, resulting in ...
Read more >
uglify-js - npm
UglifyJS is a JavaScript parser, minifier, compressor and beautifier toolkit. Note: uglify-js supports JavaScript and most language features in ...
Read more >
Minifying - SurviveJS
Since webpack 4, the production output gets minified using terser by default. Terser is an ES2015+ compatible JavaScript-minifier. Compared to UglifyJS, the ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found