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

NPM Install for hybrid node browser environments #739

Closed
techninja opened this issue Jul 28, 2015 · 24 comments
Closed

NPM Install for hybrid node browser environments #739

techninja opened this issue Jul 28, 2015 · 24 comments

Comments

@techninja
Copy link

I'm making a desktop app in Electron with paper.js, and wanted to use npm to manage the package for use as a "clientside" browser component, as it does beautifully with jQuery and underscore. Using something like window.$ = window.jQuery = require('jquery'); is all that's needed in the node enabled Electron window.

Unfortunately for me, default for npm install paper includes building for node server side with Cairo, which I won't actually need.

Should I:

  • Just use bower for everything?
  • Install Cairo so it builds then just reference the clientside code?
  • npm install --force to get around the build error for OS contributors to the project that don't want or need to install the dep?

EDIT: I'm also open to the possibility that I simply don't know enough about the Paper.js system to say either way what I should do.

@techninja
Copy link
Author

For now, I've used option 3 above and it gets me the files where I want them, which is good. It seems simply including the lib with window.paper = require('paper/dist/paper-full'); does give me the paper object, but it does not play nice, spouting the following error once a PaperScript is included on the page:

Uncaught TypeError: Cannot read property 'apply' of undefined
execute @ node_modules/paper/dist/paper-full.js:13004
(anonymous function) @ node_modules/paper/dist/paper-full.js:13039
Http.request.xhr.onreadystatechange @ node_modules/paper/dist/paper-full.js:11539
Http.request @ node_modules/paper/dist/paper-full.js:11546
loadScript @ node_modules/paper/dist/paper-full.js:13038
each @ node_modules/paper/dist/paper-full.js:133
loadAll @ node_modules/paper/dist/paper-full.js:13050

I'm supposing this has to do with node module inclusion scope restrictions (somehow), as including this file directly via <script type="text/javascript" src="node_modules/paper/dist/paper-full.js"></script> works just fine.

I'm going to move forward with this method as it works (even if it's not very "pretty"), but will keep my eyes out for any suggestions or tips if anyone has any.

@lehni
Copy link
Member

lehni commented Aug 6, 2015

We've put node-canvas into the optionalDependencies list (#664), so this shouldn't happen anymore?

Which version of paper are you installing?

@lehni
Copy link
Member

lehni commented Aug 6, 2015

Oh, you need to install it using:

npm install paper --no-optional

@techninja
Copy link
Author

Awesome, thanks. Currently pinned to version 0.9.23 (which appears to be the latest release). I can't say this is a fully comprehensive fix, but it's certainly workable and better than --force.

I'm not entirely sure what would be needed to change in the detection logic to get var paper = require('paper') to work in Electron, or if it's even on your radar to add support for. Unfortunately it's not in my time budget to find out a solution and do a PR, and if it's not in your roadmap, then I'd say we can probably close this issue.

@lehni
Copy link
Member

lehni commented Aug 17, 2015

It'd be great to support Electron fully for sure! And I agree, it would be good to find a better fix. I am wondering if we need to offer two versions of paper on NPM, one for Node.js environments and one for people working with the browser.

@techninja
Copy link
Author

Oh, sweet, glad it's on your radar! Whatever method you choose, be sure to include support for the nw.js guys. They're method is similar to Electron, and allows both DOM and Node.js API/require access in the browser.

@lehni
Copy link
Member

lehni commented Aug 18, 2015

Gee, way too many ways of packaging and loading things out there. Keeping it all on the radar could be a full time job in itself :)

@lehni
Copy link
Member

lehni commented Aug 18, 2015

So the problem is that we have two basic versions of paper.js, one for browsers and one for the headless node.js environment. The issue with electron is that it is both, and based on your use-case, you'll want one or the other. This describes the complexities that we're facing pretty well:

electron/electron#1574

I'm not sure yet what a good solution will look like.

@techninja
Copy link
Author

I think Paul on that issue said it best:

...what you want depends on what you're doing.

If we know the two supported use cases...

  1. Node side render/path management
  2. DOM Access & canvas management clientside library)

...then we can likely choose the best path for release.

For my project, I just wanted to use the same module & version management tools as node, but restrict use in my application to "clientside" only, meaning the build portion of npm install will fail as it assumes the first use case.

Perhaps modern JS libraries need to outline their use cases for the now three (node, browser, & hybrid) environments, and then only support those. I'd imagine as these things get more common, NPM will instate some kind of third category defining the hybrid environment (next to main & browser).

In this hypothetical situation, this project would define the node only main to the node only project, and both the browser and hybrid to the same clientside library. And as soon as you support a third use case you can change that to a new JS file designed with both in mind. Of course there's likely other changes needed to both the library to recognize the slight differences of a browser vs a hybrid system.

Of course none of this gets us anywhere fast unless people much further up the rungs of the ladder agree on such a thing. In the mean time, it may simply behoove this issue to discuss simpler things like providing a node only module that then requires the central library which is also the clientside/hybrid compatible library.... ?

I can't say I've done my homework to know enough about what it takes to build these or the differences between them. I may be totally off base, but I can certainly hope I've at least lended an idea int he right direction.

@oveddan
Copy link

oveddan commented Jan 3, 2016

+1

@lehni
Copy link
Member

lehni commented Jan 3, 2016

I think it boils down to this:

We should move away from the separate builds for browser and server, and create one hybrid build, or two, as we probably still want to provide paper-core.js and paper-full.js, to provide a smaller version for people who don't use PaperScript. We can keep using prepro.js to build these, but have far less branching in the preprocessing instructions.

The node.js version then can require a separate file that adds some node.js specific dependencies and work-arounds, along with this hybrid version.This would then also simplify the work on a web-worker friendly version (#634).

@oveddan
Copy link

oveddan commented Jan 4, 2016

Agreed @lehni - in recent years, there has been a big shift towards browser based applications built using webpack or browserify, which handle modularization of code and prevent polluting the global namespace, and those of us who use those tool wouldn't feel the need to really use paperscript, when we can do something like:

import paper, { view, Path, Group, Point } from 'paper'

paper.setup(domNode)
path = new Path(params)

view.onFrame = function({
})

@lehni
Copy link
Member

lehni commented Jan 4, 2016

That's not really what PaperScript is about. The main benefit is the addition of operator overloading and its use in the Point class, to simplify teaching of vector graphics and geometry.

@lehni
Copy link
Member

lehni commented Jan 10, 2016

Related: #582

@Pomax
Copy link

Pomax commented Jan 11, 2016

As an external user's contribution on the "paper-core vs. paper-full" concept, the size difference is essentially irrelevant (core is already 338kb, so if that's an acceptable payload, the extra 50kb is not going to matter either. And minified the difference is 187kb vs. only 30kb more, again that's not a big enough difference), and the memory footprint difference gets lost in the much more massive overhead of the browser itself. Maintaining a core vs full distinction is probably far less important than separating into "the bulk of the library that does the work" and "the part of the library that does the actual drawing of things using some object with a canvas-compatible API".

@lehni
Copy link
Member

lehni commented Jan 11, 2016

That's certainly worth a thought. But according to that logic, I would then much rather not do any separating at all.
: )

@Pomax
Copy link

Pomax commented Jan 11, 2016

@oveddan ah, but you still want paperscript, because writing a Webpack paperscript-loader that preprocesses any .ps files so that they get transformed to "regular" JS before getting passed into the build is (not trivial but) entirely doable. In fact, I'd love me one of those.

@lehni "that logic" being "separate the processing from the actual draw instructions"? Because I agree: you'd need very little separation. As long as a Paper.setup(canvasAPIequivalentObject) is available, and the library doesn't refuse to work if none is bound (just don't draw), that would be enough to make things work both in the browser, as well as in Node or any other "I don't have a canvas but I have XYZ" context. The one thing that might be worth splitting on is the parser vs. the library, so that it's possible to get the conversion result from paperscript to plain JS (so it can be used for preprocessing offline/serverside/whateverFadNameItHasToday) in a webworker, separate thread, etc.

@lehni
Copy link
Member

lehni commented Jan 11, 2016

No I meant the logic that 30kb more isn't a big deal. I haven't measured it but the code that does the drawing is much smaller than that, so I don't think it's worth splitting off either... I'll be working on supporting paper scopes without a view (or with a DummyView) for sure, since that's required for web workers as well.

And there's already an issue for the separate parser: #656

@Pomax
Copy link

Pomax commented Jan 12, 2016

ahh, yeah that makes sense. I have nothing more to add it seems =D

@lehni
Copy link
Member

lehni commented Jan 26, 2016

So I have started working on the transition to this unified version. First step: Make jsdom's Image object function like the browser's: jsdom/jsdom#1365 / jsdom/jsdom#1366

lehni added a commit that referenced this issue Jan 26, 2016
lehni added a commit that referenced this issue Jan 26, 2016
@lehni
Copy link
Member

lehni commented Jan 26, 2016

So since e1a51f8, this is starting to look very good. The only issue is that it requires a modified version of jsdom. I currently use it with https://github.com/lehni/jsdom/tree/paper.js, which is v7.2.2 with my work on Image / Canvas support patched in from upstream. It seems to work well, but more testing is needed.

@lehni
Copy link
Member

lehni commented Jan 26, 2016

I've merged this into develop now. Closing.

@lehni lehni closed this as completed Jan 26, 2016
@Pomax
Copy link

Pomax commented Jan 26, 2016

\o/

@pajtai
Copy link

pajtai commented Jul 23, 2019

Agreed @lehni - in recent years, there has been a big shift towards browser based applications built using webpack or browserify, which handle modularization of code and prevent polluting the global namespace, and those of us who use those tool wouldn't feel the need to really use paperscript, when we can do something like:

import paper, { view, Path, Group, Point } from 'paper'

paper.setup(domNode)
path = new Path(params)

view.onFrame = function({
})

@oveddan is that how you use Paper with npm / webpack? It'd be great if that was included in the examples. All the example use attributes on script tags, which isn't always convenient.

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

No branches or pull requests

5 participants