fde31 / max-js-bundler

CLI Tool to bundle and transpile modern JS for usage in [js] and [jsui] in Max MSP. The idea is basically to support writing modern Ecmascript code alongside the usage of NPM dependencies within your code.
MIT License
23 stars 6 forks source link

global namespace collisions (fe. Buffer object) cause a circular dependency issues or do not behave as expected #6

Open devanecondition opened 4 years ago

devanecondition commented 4 years ago

First off, thanks for making this! It's really helpful.

In my app, I tried to use Max's Buffer constructor:

var RandomFileBuffer = new Buffer('randomfile');

and I get the following error on build:

Circular dependency: ../../../../../usr/local/lib/node_modules/max-js-bundler/node_modules/core-js/modules/_array-copy-within.js -> ../../../../../usr/local/lib/node_modules/max-js-bundler/node_modules/core-js/modules/es6.array.copy-within.js -> commonjs-proxy-/usr/local/lib/node_modules/max-js-bundler/node_modules/core-js/modules/_array-copy-within.js -> ../../../../../usr/local/lib/node_modules/max-js-bundler/node_modules/core-js/modules/_array-copy-within.js

I am guessing core-js has a clashing Buffer object? Not sure. I seem to have a few issues around core-js compiling correctly. String.split() for instance throws and error and causes me to quit/restart Max.

Thanks!

devanecondition commented 4 years ago

Should be fixed in: https://github.com/fde31/max-js-bundler/pull/7

fde31 commented 4 years ago

I've looked through your Pull Request and merged it into a temporary branch. FWIW while things compiled correctly I was not able to get things running within Max due to the core-js line String(String).split(" ")which triggers a recursion error.

When thinking about working with Max Globals and them clashing with existing names during the transpile I started wondering if this tool is trying to do "too much" by offering packaging of NPM modules at the same time while bringing more modern JS Syntax to the js Object.

Some things will work of course but other's won't and I'm inclined to say the tool should focus on one task: more modern EcmaScript support in the js object and leave NPM packages to themselves, that might have an assumption to run within a Browser or Node context, which simply is not the case.

If we can get alignment on that I agree that it might be good to get something in place that prevents Buffer but also potential other built-ins from being transpiled. Additionally I think this might free up some resources to get broader Language Spec support specific for Max using the bundler (setTimeout, setInterval, Promises etc).

There are a few others that seem to be using this tool actively so I'll try to reach out to them in order to get a bit more clarity on the expectations

devanecondition commented 4 years ago

Thanks for taking a look @fde31 -

I think I agree about the NPM packages. As I played around more with with my project, I realized that the custom rollup may be unnecessary if the Max js's this is exposed somewhere. Example:

This function:

function bang() {
    post('the js object received a bang');
}

also works with this syntax:

this.bang = function () {
    post('the js object received a bang');
}

I've been handling this with an extra script in node that prepends these Max variables to the bundled build script:

var MAX_MSP = {
  Buffer: Buffer,
  File: File,
  Folder: Folder,
  Global: Global,
  Image: Image,
  LiveAPI: LiveAPI,
  Maxobj: Maxobj,
  Patcher: Patcher,
  PolyBuffer: PolyBuffer,
  Sketch: Sketch,
  SQLite: SQLite,
  SQLResult: SQLResult,
  Task: Task,
  Wind: Wind
};
var maxThis = this;

Using maxThis (maxThis.bang(), maxThis.patcher), I no longer need to rely on the global namespace.

devanecondition commented 4 years ago

BTW, this list of variables has to be updated, as it seems the latest version has added some new classes (MaxobjListener, ParameterListener, ParameterInfoProvider, etc)

aumhaa commented 4 years ago

I also agree that this tool should probably focus on transpiling for Max [js]. Maybe then it could be used as a basis for another project that could incorporate it and be more specifically tailored for dealing with package importing if so desired. As a tool to unify syntax/style between [nodescript] and [js] it seems pretty useful.

I can't think of a lot of existing rpm packages being usable in the context of Max [js]. Most everything I've wanted/tried to transpile has Node or native extension dependencies. If the tool is going to transpile package dependencies for use in Max, should it determine and notify if the build won't work in Max due to basic limitations?

I've been using a simple Promise polyfill in [js] to deal with async communication between [nodescript] and [js], but I don't know if you'd want to go that route or something more mainstream like rsvp or bluebird? Anyway, I'm happy to help if I can.

devanecondition commented 4 years ago

Sorry, I totally misread about the npm packages... I thought it was more a question if it’s worth it/needed to modify existing packages like rollup for this bundler.

I have been using this to build a pretty involved app that has many npm dependencies - redux and immer being the core architecture.

My hope is to find a pattern similar to the react/redux pattern many web engineers use right now. I think a lot of people could find that helpful for their patches. Between max-js-bundler, redux, and some of the new objects for max’s JS object, I think it’s pretty close.

fde31 commented 4 years ago

Interesting. Sounds like a cool project although I still lack all of the context to fully understand what you are trying to achieve/ offer. Would you share more? If too sensitive you can also reach out via email. It’s my first name “florian” at cyling74.com

For the scope of this work. Does your bundle successfully load within the [js] object?

I do see sort of two distinct things here. One being the pure transpilation of a modern ES spec to the one that’s supported in the Spidermonkey Version that’s used in [js] in Max. The other is a bundling feature / tool.

I’m happy to support the effort for the former and come up with the necessary configurations but probably also custom Babel plugins to help transpile. If people then have a need to make use of bundling that could be a separate project, maybe maintained but someone who has a need for this? I’m still a bit hesitant as a lot of NPM packages might either rely on Web APIs or Node APIs being present making it not really transparent for the user why certain things might just fail within [js].

However, we might could eventually come up with a whitelist of things that are supported from the Node API (and therefore included with a polyfill) and load as they have no runtime dependency. But maybe that’s a phase 2.

Any input?

On Sat 13. Jun 2020 at 17:34, devanecondition notifications@github.com wrote:

Sorry, I totally misread about the npm packages... I thought it was more a question if it’s worth it/needed to modify existing packages like rollup for this bundler.

I have been using this to build a pretty involved app that has many npm dependencies - redux and immer being the core architecture.

My hope is to find a pattern similar to the react/redux pattern many web engineers use right now. I think a lot of people could find that helpful for their patches. Between max-js-bundler, redux, and some of the new objects for max’s JS object, I think it’s pretty close.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/fde31/max-js-bundler/issues/6#issuecomment-643646794, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAIRHRPKAOGBW3633M4MTSDRWOTATANCNFSM4LOERD3Q .

devanecondition commented 4 years ago

Thanks, my project is quite large, but I will try to make a small example for context.

I can understand the hesitation of allowing NPM packages to be bundled, but as a frontend engineer I've found it really helped me make a more robust application.

If I am using Max to build an audio application, I want to use Max for its audio msp~ object patching, and the UI elements for control. When it comes to things like state management, complex logic, or even simpler things like string concatenation, I wanna use javascript. And there are many open source npm packages that handle that very well, with no environmental dependencies. I don't wanna have to rewrite that kind of functionality if it's already out there in a popular repo.

Also, when developing with [js] inside max, you only have the Max Console window for debugging, which is challenging. I have been using typescript to help me catch bugs, and with npm packages available, it would very easy to set up testing, ci, etc... for more insight when things go wrong.