Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Webpack configuration for bundling libraries compatible with flutter_js #38

Closed
fbennets opened this issue Apr 28, 2021 · 6 comments
Closed

Comments

@fbennets
Copy link

Hi @abner,
first and foremost, thank you for this awesome library!

I have currently have an issue where I am trying to load our own JavaScript library which is bundled with webpack as an UMD library. I managed load a generic JavaScript file containing some test functions and executing them afterwards using the AJV example. Loading the bundled library in a browser using a "script"-tag in an HTML-file works fine, its available in the window/global namespace. However, when I'm trying to load the library using flutter_js, it does not become available in the global namespace.

I saw you mentioning that you are using webpack to bundle libraries you load into flutter_js. Therefore, I wanted to ask if you could kindly share your webpack.config.js and how you are exporting you library to the global namespace? Afterwards I could do a PR to enhance to documentation on how to embed libraries, if you'd like me to.

This is the library I am trying to embed:
index.js

The export in the library is done this way:

class Render {
...}
module.exports = Render;

I also tried export default class {...} which also worked fine in a browser but not in flutter_js.

This is the webpack.config.js:

module.exports = {
  entry: './src/index.js',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'open-decision-js-core.js',
    library: {
        name: 'OpenDecisionJSCore',
        type: 'umd',
      },
  },
};

The loading of the library in flutter follows your example:

String libJS =
            await rootBundle.loadString("assets/js/open-decision-js-core.js");

        this.jsRuntime.evaluate("""var window = global = globalThis;""");

        this.jsRuntime.evaluate("$libJS");

However, in the following calls, global.OpenDecisionJSCore is undefined.

I'd really appreciate some guidance!

@fbennets
Copy link
Author

I solved the issue, the eval of the library failed, as I used some syntax which WebKit on MacOS didn't support yet. Took me some time to figure out that I'll only see syntax errors when wrapping the line this.jsRuntime.evaluate("$libJS"); in a print statement.
I'll see if manage to write some guidance on importing libraries using flutter_js in the next weeks!

@suraj740
Copy link

suraj740 commented May 3, 2021

@fbennets i am also using some custom library bundled with webpack but i am getting error Can't find variable: document.
do you have any idea?

@fbennets
Copy link
Author

fbennets commented May 3, 2021

I guess that's not an Webpack issue. In a browser environment document contains the wepage's DOM tree (see here). So you're library is trying to access the DOM which is not present, as you're not executing JS within a website/browser environment. What are you trying to do? If you're trying to render elements using JS, you're probably better of with using a webview plugin in Flutter (like flutter_webview_plugin or webview_flutter . They should allow you to execute Javascript to render elements or manipulate the DOM.

Oh remember that loading the .js file with the root bundle - as in the AJV example - is asynchronous. Make sure that you await until the library is fully loaded.

@suraj740
Copy link

suraj740 commented May 4, 2021

@fbennets I want to load js bundle in my flutter app

String test = await rootBundle.loadString("assets/library/index_bundle.js");

            print(test);
            javascriptRuntime
                .evaluate("""var window = global = self = globalThis;""");

            var lib = javascriptRuntime.evaluate(test);

@stonesong
Copy link

stonesong commented Feb 29, 2024

Hi @fbennets do you have some example ? I can't manage to run a js library that I bundled with webpack.
First I created a test.js file like so:

class Render {
  constructor() {
    this.message = 'Render instance created';
  }

  getMessage() {
    return 'This is a message from the Render class.';
  }

  static staticMethod() {
    return 'This is a static method call from Render.';
  }
}

module.exports = Render;

and then I loaded the file with flutter_js and executed it like so:

 String message = jsRuntime.evaluate("""
        var renderInstance = new Render();
        renderInstance.getMessage();
      """).stringResult;
    print('Message: $message'); 

So far no problems, it is working.
Then I moved this test.js file info an src/index.js of a library and bundled it like so:

const path = require('path');

module.exports = {
  mode: 'production',
  entry: './src/index.js',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'test.js',
    library: 'testJs',
    libraryTarget: 'umd',
  },
};

Moved the bundled file instead of my test.js in Flutter that was working before, but then no way to have it working whatever I do:

String message = jsRuntime.evaluate("""
          var renderInstance = new testJs.Render();
          renderInstance.getMessage();
        """).stringResult;
      print('Message: $message');

      String message2 = jsRuntime.evaluate("""
          var renderInstance = new Render();
          renderInstance.getMessage();
        """).stringResult;
      print('Message: $message2'); 

I always get the:
flutter: Message: ERROR: Can't find variable: testJs
at global code@
flutter: Message: ERROR: Can't find variable: Render
at global code@

What am I doing wrong ? Thanks a lot in advance

@stonesong
Copy link

found a solution using:
libraryTarget: 'var', globalObject: 'this',

in my webpack config

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants