-
-
Notifications
You must be signed in to change notification settings - Fork 22
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
Issues with dev environment and consuming Node packages #190
Comments
Thanks for opening this @jgaehring! This stuff should definitely work more smoothly - or at the very least be clear about which use-cases are supported.
I agree having the main example default to "MapBox" is a little weird, we probably should change that, but you probably won't notice it much if once you choose "OpenStreetMap" as I described above because farmOS-map should remember that selection.
We should definitely improve the language there and add a note about building the top-level package first. (or maybe do it automatically somewhere in the flow that doesn't cause it to get rebuilt unnecessarily too much)
Yeah, that's a bit confusing. That part of the documentation is definitely aimed at folks who are wanting to build against the code in farmOS-map, but externalize the dependency to the dist artifacts. Vite also has a mechanism for handling externals as I recall, so I think it should work similarly there. That said, the other use-case would (potentially - this might be a bit more into the untested tall grass) be building farmOS-map as a whole into your application. In that scenario, I think your application bundler would handle the mechanism by which the CSS is bundled/loaded. Some of the discussion in the following issues may be helpful; |
Ohhh, this is tremendously helpful, just at a glance (need to be stepping away from this for the day unfortunately). I'm happy to submit changes to the README if I can (wouldn't have been so nitpicky if I didn't intend to 🙂) and if I can find some ways to incorporate those suggestions back into the project, and you think they'd be helpful, I'm happy to open some PR's for that, too. Should make for easier integration with more projects. Thanks for the insights! |
I'm wondering about this possibility again:
Is the If so, this strikes me as a bit counter-intuitive as a library, where the distributable is inferred to be the library itself, not an example application, but perhaps there are other factors I'm not privy to. The reason I ask is I think it would be ideal to be able to import farmOS-map or parts of farmOS-map using the regular module syntax (ie, I realize that straight-up changing that would be a huge breaking change, so I wonder if in the meantime we could structure things a bit differently, as: .
├── dist/ # Decide long-term purpose of this; deprecate all else.
├── examples/ # No change.
├── lib/ # For npm package consumers, in the following formats:
│ ├── cjs/ # - CommonJS (ie, using require() instead of import)
│ ├── esm/ # - ECMAScript Modules
│ ├── umd/ # - Universal Module Definition
│ ├── farmOS-map.css # optional
│ └── farmOS-map.js # optional
├── src/ # No change.
└── www/ # Build artifacts for https://farmos.github.io/farmOS-map. While I think there are arguments for how Looking at the The critical thing about The other nice thing about this is we can make the whole "clobbering the global And sorry for making this such a long tome, but I was going to try to open a PR for this then I ran out of time to get a working implementation together and have to put this aside for now. I may also be unable to follow up for the next few weeks on this issue (currently on a collision course w/ a major burnout), so I wanted to just get all my thoughts and rationale out of my head before it was lost to the void. 🌀 |
I probably don't know enough to respond to all this thoroughly, and sorry if I say something dumb/obvious, but maybe it's helpful... :-)
Apart from examples, You can see how the farmOS-map/.github/workflows/release.yml Line 31 in c73bd7c
Here is where we look for that file in farmOS: https://github.com/farmOS/farmOS/blob/9587872ea9e42f749ebf123214dd17ed0367fcf1/composer.libraries.json#L13
Is it not optional currently? 🤔 I believe #117 made this possible, and Quoting that PR:
It sounds like you're experiencing issues with that code specifically @jgaehring?
Maybe we should drill into that specifically? Were there other specific errors? |
That's definitely the intention... though I think it may still be necessary to manually include the CSS somehow. |
Ohhh, maybe I was trying to import the wrong function/class. I was looking for a way to get the Still, assuming that works, I believe there could be better ways of restructuring the build process (and/or README) to be more in sync with typical JS development workflows and expectations. I know we looked at this a little in #188, but at the time I was too unfamiliar with the updates to farmOS-map's intended usage since 2.x (eg, I don't recall there being a
I've been doing something similar for farmOS.js (I forgot until now there is also a
This is something I've also encountered, but once again, Rollup has a I imagine Webpack has similar tooling like this, but it might be worth considering a migration to Rollup in the future, particularly if and when a Webpack upgrade is required. Rollup is drastically simpler to configure and keep up-to-date, and it has been the de facto standard for library bundling for the last 5 years now or more. It's also nice that it is the bundler underlying Vite (combined with esbuild for faster transpilation, compared to Babel), so it works well to pair Rollup as a library bundler with Vite as an app bundler, since they can share configuration. As for the README, reflecting on this now, I think it would make sense to include something at the beginning of the "Usage" section that explains the separate workflows for the global instance and the instance manager before jumping straight into the various methods for creating maps and layers. Neither workflow strikes me as particularly intuitive, and that's not meant as any shade, just that I think it merits some explicit instructions to point out that:
I feel I made a bit of fuss over getting too specific into possible Webpack configs and all in the "Usage" or "Installation" sections, but to my mind that is not quite the same as making it clear what the main interface is for interacting with farmOS-map instances. I still don't that consider part of the "Installation" process per se, but I do think it merits placement at the very top of the "Usage" section. |
Cool! Whatever we can do to make it easier to use farmOS-map in common and best-practice contexts, I'm all for! I don't have a strong opinion on the specifics, as I don't work in that world myself, so I'll leave those decisions to other stakeholders. :-) Fully agreed on the
Ah gotcha. Perhaps we should open a dedicated follow up for that piece specifically? While leaving this open to broader ideas?
Here is the PR to give that more context: #116 The tl;dr is: this is mainly for consumers of the pre-built |
Ohhhhhhh, this was the missing piece of the puzzle for me actually. For some reason I thought those chunks were for other JS bundlers, but they're for farmOS itself then? And I assume there's some PHP somewhere that adds the proper script tags to the HTML, based on whatever it finds in there? That makes a lot more sense, I was confused by how they'd all end up being added back to the
Maybe. There may already be a way this is figured in when using the |
Yes exactly! Basically PHP code in farmOS core says "add The challenge we were running into was: with each new feature/option we added to the farmOS-map library, that So if you look at the map JS that is being loaded on the farmOS dashboard, for instance, it may be different than the map JS loaded in a different context (like a quick form with a simpler map). That's the idea anyway. It's primary purpose was performance, given the unique modular uncertainty of client-side code in farmOS core. :-) |
FYI, I'm getting the same issue with import MapInstanceManager from '@farmos.org/farmos-map';
import geotraceCtrl from 'farmos-map-geotrace';
const units = 'metric';
const mapMgr = new MapInstanceManager();
const instance = mapMgr.create('map', { units });
instance.addLayer('vector', {
title: 'Drawing',
group: 'Editable layers',
color: 'orange',
}); And here once again is that same error: ✘ [ERROR] No matching export in "../../node_modules/@farmos.org/farmos-map/src/styles.css" for import "clusterStyle"
../../node_modules/@farmos.org/farmos-map/src/instance/methods/layer.js:17:22:
17 │ import colorStyles, { clusterStyle } from '../../styles';
╵ ~~~~~~~~~~~~
5:39:33 PM [vite] error while updating dependencies:
Error: Build failed with 1 error:
../../node_modules/@farmos.org/farmos-map/src/instance/methods/layer.js:17:22: ERROR: No matching export in "../../node_modules/@farmos.org/farmos-map/src/styles.css" for import "clusterStyle"
at failureErrorWithLog (/home/jamie/Code/farmOS/geotrace/node_modules/esbuild/lib/main.js:1636:15)
at /home/jamie/Code/farmOS/geotrace/node_modules/esbuild/lib/main.js:1048:25
at /home/jamie/Code/farmOS/geotrace/node_modules/esbuild/lib/main.js:1512:9
at runMicrotasks (<anonymous>)
at processTicksAndRejections (node:internal/process/task_queues:96:5) |
Hmm yea that jives with what @symbioquine said above:
Sounds like that's a specific bug to be fixed (but maybe can be worked-around in the meantime?) |
Might be more trouble than it's worth for a workaround, honestly, b/c I don't really know how that would be done at the moment, but a dedicated build process for module systems (both bundlers and native ECMAScript module usage, neither of which seems to work currently) wouldn't be terribly hard. For reference, based on the Rollup config I'm using currently for the project I mentioned above, I think a pretty straight forward configuration like that could achieve something similar here, while also potentially opening up a pathway for a less complex, more easily maintained build process in the long run. |
And to clarify, I don't think there's a bug w/ The bug, imo, is that so long as the |
I'm just catching up here...
It seems like that import shouldn't have anything to do with the CSS. Presumably something in your build configuration @jgaehring is causing the reference to |
I'm not sure it's great for them to have the same name (the code directory and the css file), but it is also surprising behavior IMHO for the import to resolve against the css file automatically. |
Ah, that makes sense. But I think it still reinforces my later clarification:
Since inferring |
Actually, it's inferring
How imports are resolved isn't specified by EMCAScript spec at all as far as I can tell. However, some conventions have arisen around it. Since Node.js resolves imports of directories to In contrast, inferring the
There is a balance here. We should probably avoid patterns that are needlessly coupled to Webpack, but we probably also should accept that it won't be worth our time to guarantee farmOS-map builds under all build system/conditions. In my mind imports from directories is a pretty well supported build environment feature (including in Rollup with a plugin like rollup-plugin-local-resolve). I'm not sure what the best path forward for builds with Rollup, but I'm curious to see what happens if you try with the rollup-plugin-local-resolve plugin... Slightly unrelated, but another interesting example is the use of Webpack's chunk splitting. Although that probably will only work in Webpack, it also should gracefully degrade under other bundlers. (Because the pragmas are comments that would just get ignored.) |
For browsers: For Node: But I think we're overshooting the point here, which is that the standard practice for npm packages is to provide a distributable that can be consumed in one or all of the 3 main module formats, CommonJS (CJS), ECMAScript Modules (ESM) or Universal Module Definition (UMD), without special bundler configuration required downstream. Pointing to What I'm suggesting is a way to make this library work for npm consumers that doesn't require restructuring the entire project and, as I noted above, doesn't require any breaking changes either. It just means adding a separate but very simple build configuration, outputting that to a separate location as a distributable ( Again, if you want more background on this, see the Rollup Wiki, which reflects the direction most of the JS ecosystem has moved since it was first published in 2017: |
To be clear, I'm not necessarily arguing against the strategy of transpiling the farmOS-map source code to ESM/CJS versions. However, I do think that there are some details we should pay attention to if we go down that path;
Mostly irrelevant replies to earlier parts of the thread
I believe those are just documentation about how specific implementations behave, not necessarily what the EMCAScript spec says. I'll admit that I'm certainly not super well versed in the EMCAScript specification, but I've read in a few places that import resolution isn't specified - and a brief skim of the modules/import/export sections of the spec (page 269 - actually 289 of the pdf - on) seems to confirm that it doesn't provide any details about how imports actually get resolved from the filesystem/network/etc.
Strictly speaking, that also could be considered a breaking change for any project that is currently depending on the |
I've been trying to set up a development environment for adding new controls, behaviors, etc, either as a third-party extension and/or to include in the official repo.
First I tried to simply clone the repo and branch off
2.x
to experiment a bit with the examples. To start off, I found the README a bit confusing in the way it describes using theinstall-all
script "in each example project", when theinstall-all
script is not included in each example, but at the root of theexamples
directory itself. It also doesn't mention that the examples depend upon the distributable version of the library, which needs to be built first.Those are really minor issues, but ultimately, it all seemed to be in vain, b/c most of the examples require Mapbox API keys to work. I really don't know if the examples are at all intended for this purpose, but if so, it might be helpful to include an OpenStreetMaps example that's a little more sophisticated than the
minimal-html-consumer
.The root-level
npm run dev
script, which is recommended under the README.md#Development, also seems to use thesimple-html-consumer
example as its base, so this too breaks w/o the Mapbox API keys.After that I switched tracks, since it seemed like the
examples
weren't really intended for development, but for the farmos.github.io only. So I initialized a vanilla Vite project with farmOS-map as an dependency consumed via npm. Here I ran into a number of errors, based largely upon the way that the rootpackage.json
points tosrc/index.js
as the main entry point, but there seem to be some bugs if not using Webpack and/or a similar configuration as the rootwebpack.config.js
.One issue was with
clusterStyle
import, which frankly I don't fully understand, except it might be looking in the wrongnode_modules
directory, or something to do with the order of the imports, maybe?I circumvented this error simply by removing the offending line in my
node_modules/.../layer.js
for the time being, but then I ran into a separate runtime error with the way the OpenLayers CSS are being imported:I suspect that this is avoided with the distributable b/c Webpack bundles that CSS and adds the proper script tag to the example
index.html
or just injects it into the JS bundle itself. The README has some recommendations for this, but I'm not really sure I understand these instructions. It states:But that seems to infer one is consuming
farmOS-map.js
andfarmOS-map.css
fromdist/
, yet thepackage.json
points tosrc
, so that is where most bundlers and Node projects will look for them.So I guess I'm left with two main questions:
window
object, likedist/farmOS-map.js
does, but make them more bundler-agnostic and npm-friendly than drawing directly fromsrc/
? Something like, say,lib/index.js
andlib/index.css
?The text was updated successfully, but these errors were encountered: