-
-
Notifications
You must be signed in to change notification settings - Fork 432
Write app to src/node_modules/app
?
#551
Comments
What about just fiddling with the |
I don't think that'll work with Rollup, not sure about webpack. Either way though it's basically another form of aliasing which means it has the same drawback of hiding implementation details, which runs counter to Sapper's 'show your work' philosophy. I think there's a lot of value in people being able to see how their application is constructed, rather than keeping it in a black box |
2 things:
Using a nested |
re So it needs to be Interesting to read that PouchDB thing |
I like this idea, even if it's weird. I made a little bit of a rabble about cache busting in the Discord channel. I would say as long as |
Bit of a 'potential' issue that is unverified, some build systems/plugins/tools may look check for something being in/out of node_modules through a regex on the path or similar check, and may incorrectly flag the existence of |
Seems to me like a fine idea. |
An SSR capable Code base router like vue-router provide more freedom and options to define routes than file-based routing. We should consider switching to code based router. We can use router api (defineRoutes, goto) to define routes in code and then pass the router to sapper.middleware on the server and sapper.start on the client. |
@tbillington makes a good point — definitely something to watch out for. I think most tooling probably checks if a path is in @tomcon The easiest way to control it is probably to expose a CLI flag. We already have
You should consider switching to a different framework 😉 The whole point of Sapper is that it provides the ergonomic affordances of fs-based routes. Code-based makes SSR a lot harder, and component-based makes code-splitting a lot harder. |
It's difficult to switch to a different framework If you have used amazing Svelte/Sapper but no framework is perfect. every framework has its own merits and demerits. SSR capable code based router is on my wishlist for Svelte. |
This is working in the Svelte 3 PR, #538.
It'd be great if they could all be a single package but |
Newcomer here. I know I'm late to the party but here's my experience. I only found out about Svelte and Sapper a few days ago and was immediately drawn to the cleanliness. However... having just discovered a Aliasing the Sapper folder might add a bit of complexity to the build config, but it's much better than adding complexity to the main workspace by poluting Convention over configuration was what sold me on Sapper and I can't believe intuitiveness and convention got sacrificed for the purpose of a slimmer build config file. I'm baffled. |
Having additional |
I'm talking about the elephant in the room. Generated readonly code in a
It's not just a convention, it's even in the name src = source. Src contains the source files for what you're generating. Not the other way around. I want to call it a structural antipattern, but it goes beyond that. I have a great deal of respect for Svelte and Sapper and would love to use it, cause there's so much to love. For now I cross my fingers and hope that some day the source folder will become the place for source files. |
They are source files; they are the files that are used to generate the built files. They are specific to your application, just like the source code you have written yourself. The only difference is Sapper generates them for you. |
The difference isn't that Sapper generated them. Generated files are common in src folders. Boilerplates created by CLIs etc. The real difference is that they're internal readonly files that I can't work with. As such, all they do is clutter up the one space I'd like clutter to be abstracted away from. |
Put a little piece of tape on your screen where the folder name is and it won't feel as cluttered. |
You can generally configure editors to hide gitignored folders |
I have told vscode to ignore all folders I don't want to see. It's wonderful really, then I am not worried about having to look at them or why they are there. |
i have also suggested adding a README to the generated folder to ease the surprise i and @jakobrosenberg had. |
Seeing this thread reminded me I've seen a few tools around that go through your computer to delete all the node_modules folders to free up space. I've used one in the past and recovered +10gb.. so I see their value. I don't know if any of them would safely handle (leave alone) node_modules inside src though..!! Just putting this here to be documented in some form. |
For anyone who'd prefer to keep modules within Edit package.json and change Note: I still haven't figured why |
Because it is app-specific source code, not an unchanging, reusable module. Putting the sapper code into the root This may or may not break things. |
seems fine since |
Indeed @necauqua, this was just an awful design-decision to put auto-generated code into the I can't believe the argument of @Rich-Harris:
Is the build-config going to change so often that the effort for maintaining it is going to be a burden? Heck, I fell immediately in love with Svelte and Sapper...and then this... ...Grandma was right, every time you think you are in heaven, reality pulls you back again. |
People, if you think it's preferable to do import { app } from '../../../../../../__sapper__/client.js'; than to realign your perspective a bit on what constitutes source code, then... you're just wrong. I'm not sure there's a kinder way to put it. Sorry! I'll often have scripts in all kinds of projects that fetch some data or create some module then write it into my Cast off your preconceptions. Try it for a bit. Start putting common components in |
True, this is not a solution either. The solution would be to include it within the build-config where it belongs. For now I just use the fix that @jakobrosenberg provided. Yet, I'm asking myself what the side-effects are. Everything seems to be working...till now. So @Rich-Harris, what is the drawback of having this as default:
|
In the build config where it belongs. As opposed to leveraging the default, built-in, thats-how-it-is-supposed-to-work, node_modules resolution behaviour? |
The drawback is that the next time you do Trust me, we don't make these decisions quickly or arbitrarily. We do know what we're doing! In fact I wrote this at the very top of this thread:
|
@Rich-Harris I don't think it's appropriate to call people who have different perspectives "wrong". The issue here is that it's uncommon, unexpected, and undocumented behavior. |
I'm afraid this is not true. This is precisely why the node_modules resolution algorithm works the way it does, to give you flexibility to leverage it in your source code. This is default behaviour and, while it might not be widely known, it is definitely expected. |
@pngwn it's expected with external packages, but not with app specific code. |
Unfortunately this is ahistorical. The node resolution algorithm predates npm; early Node tutorials encouraged you to put your own modules in
I don't like to simply work on projects to satisfy people's existing mental models, I like to use these projects to expand people's models of how code can and should work. The reliance on ugly hacks like adding aliases to our build configs (which then have to be duplicated for the benefit of typecheckers, linters, editors, etc) are an artifact of people not having general awareness of how things like |
The stuff in |
@Rich-Harris you are actually starting to expand my mental model 🔮 |
Well, the existing mental model is that the src folder contains the files you wrote and you manage. I don't know why it suddenly needs to be changed to the 'well yeah but also there is a node_modules folder - yup, same name as the one that you already learned to be afraid of and also never ever checking it in VCS (that one you also have one level above btw), and so this one is managed by something else, so ignore it plz'. This whole argument above about the evolution of node_modules folder makes little sense - so you are using the module resolution designed for something else as a hack, and right after that you say we don't want stuff to be hacky or use aliases or whatever, we want to change the mental model (to what?). So weird and pointless, for me at least. Also there exists a concept of a generated sources folder, it even has a separate icon for it in IntelliJ, why won't you use something like that, idk. Okay, I wanted to end the message here, but I've read the whole thing again and here is what I understood: So anyway I have to conclude that this all is really weird and perhaps I would wait/ask/contribute for some tools for autogenerated source code in the npm itself. Anyway, as I've said some time before above, there is a switch for me to get this sweet-sweet non-polluted src folder at expence of having to rebuild the project (I guess?) after |
This has absolutely nothing to do with npm. The node_modules resolution algorithm is not related to npm. As Rich stated npm came after node modules was implemented and npm simply leverages it. And this is not a hack in the slightest, it was explicitly designed this way for a reason. You might not like the design, but you need to take that up with node. |
Again, as written in #551 (comment):
It's not written in stone anywhere that Is |
Okay, not npm but node, or webpack or who does the actual resolution - resolving stuff from src/node_modules just looks like a historic quirck of some sort. I get that this is the best you can do maybe at this point and you cannot do anything better, but what I don't get - is you defending this obviously wacky solution like it is the best thing you've ever done and that this is how it should be done.
Well, yeah, but is seem most reasonable, nobody nowhere ever puts generated code just right into src (point me to such things if you know them, I am interested) and your point about formatters is pretty far-fetched since you are trying to find fault in my point with your 'every character written by you' that I've never said. From googling why the src/node_modules exist in the first place I found out that it is too weird for most people (what a surprise) and instead of your 'I'm gonna change how everyone thinks' mindset they chose other solutions. Okay, ending the argument, now the actual question since I know less than you anyway (yeah this statement might lead to you not changing your mind because meritocracy, but you wont change it anyway so I can remind you of that fact because humans like that): Is npm nuking it out from the big node_modules even bad? Wouldn't the thing just be regenerated on next build/run? I feel like I am missing a point here (ok maybe regeneration is time-consuming for big projects idk). |
I'm not proposing one method over the other, just addressing a biproduct of the mental model that might have gone unnoticed. We assume from conventions, that a
Good conventions lead to good DX. On a side note. I don't get the nuke reasoning. Isn't the folder generated at runtime and won't it be regenerated if it's missing? |
This might be the mental model that a lot of people currently have, but it's simplistic at best — the boundary is more porous than that:
It is regenerated when you change the structure of your application (by renaming files in All this is moot though, because no-one has come up with any workable alternatives. (Aliases are a terrible, horrible, no good, very bad workaround, and we will not be using them.) Please restrict any further comments in this thread to sensible and considered alternatives rather than griping about aesthetics, or we'll have to lock this thread, because it's not going anywhere. |
Again, it makes no difference to me. I'm just here to provide feedback as long as it's helpful. 🙂❤ A couple of alternatives
Both may come with drawbacks. Especially option 1 might clash with how tools like yarn and pnpm resolve modules. Someone smarter than me might see a way to do either without drawbacks. As for the mental model, I think it's important to differentiate between
I know the last half isn't constructive in terms of an alternative solution, but it could help when weighing the pros and cons. |
I think the issue with all of the alternatives that people suggest is that they require additional complexity and maintenance. The default behaviour might be upsetting to some due to how npm-centric the javascript ecosystem has become, but it is default, specced behaviour and requires no additional work to function. It is unlikely to change regardless, we understand people's concerns but are happy with the trade-offs. |
@Rich-Harris, just to put the atmosphere of the discussion into the right setting. I'm thankful for Svelte/Sapper. It seems that this discussion is just based on an imbalance of knowledge as @necauqua pointed out philosophically using meritocracy. Yet, it is important to state the drawbacks and advantages of people's suggestions of their solution to this issue, instead of arguing like a prophet that you are here by changing our mental model...We are developers/SEs, not some backwoods. We need the understanding why the provided solution is not feasible.
Regarding 1., I'm not sure what you mean by that exactly, @jakobrosenberg Regarding 2., I think @Rich-Harris stated the drawback of this alternative and I think that I understood his point of view now. Please confirm/correct me if I'm right/wrong, @Rich-Harris: By putting
Thanks again to everyone that works on Svelte/Sapper! Yet, I think it is important to have a clear understanding of your decision for others that get surprised by a |
I don't think that was Rich's intention. Svelte has a long history of going against convention because we don't think the current ways of working are particularly fruitful, this is another case of that. There is lots in Svelte 3 that go against common practice and that people weren't sure about at first but quickly got used to as they saw the benefits. This is a similar situation, in some ways it is less controversial because we are actually removing a bunch of work and complexity in taking the current approach, and deferring to standard behaviours. |
@moon-bits, if you know the location of the generated files, you can import them from within a package and from there export them. a-package export * from './path/to/generated/file' user code import {foo, bar} from 'a-package' A third option C) would be to import Sapper at the root level of the app and sharing it through Svelte's I've used variations of both. @pngwn I fully agree with your critical approach to conventions. Even if I think the costs outweighs the gains in this specific case. |
@jakobrosenberg, then why not simply define some webpack alias? import { app } from '../../../../../../__sapper__/client.js'; We could define a webpack alias, called 'sapper-internal' that makes it easier to import the app object. import { app } from 'sapper-internal/__sapper__/client.js'; This issue is also visible when trying to import a component outside the import MyComponent from '@/components/my-component'; instead of (current approach) import MyComponent from '../../components/my-component.svelte'; @pngwn When you say that it increases complexity and maintenance, are you referring to that? AFAIK defining webpack aliases is pretty simple: //...
resolve: {
alias: {
'$@': path.resolve(__dirname, 'src/'),
}
} |
Sapper supports two bundlers. I'm personally of the opinion that aliases are a poor solution, in order to work out where things actually live, you have to go and read through a bundler config which is often not a simple task. |
Hmm... I'm more confused right now 😕
|
Aliases are arbitrary, node modules resolution isn't.
We aren't adding any lines, making it even more absurd. |
That's why. 😋 @pngwn random aliases are bad, yes. Exceptions for root or a framework... I don't know. |
This seems a bit like bike shedding to me. I'm not sure what practical problems this has caused anyone. If we all have time to spend on this issue then surely we also have time to spend on all the real issues like adding TypeScript support, preloading assets, SPA mode, etc., right? 😄 |
Just going to spell this out once and for all: Why aliases are a terrible idea and should never have been inventedIn Sapper's specific case they're particularly bad, because you can't just define them in one place — you need to define them for each of the three configs (server, client, service worker), and since we maintain a project template for both webpack and Rollup, multiply that by two. But they're not just a bad idea in the context of Sapper, they're a bad idea period. Add aliases to your webpack config, sure, but then your editor doesn't know about them, so you can't take advantage of handy things like auto imports and whatnot when writing .js files (and .svelte files, as editor extensions improve). Nor does your linter, or your typechecker if you're using TypeScript. So you need to figure out how to add those aliases too. Who knows how that extra maintenance burden will manifest itself in future if new tools like Snowpack and Vite become popular? All this bullshit configuration, multiplying itself and forcing its way into new tooling, creating technical debt all over the place. Just madness. And totally unnecessary. Proxying is an interesting notion, but it's restricted to a single module. So you need to create separate proxies for these... import * as sapper from '@sapper/server';
import * as app from '@sapper/app';
import { timestamp, files, shell, routes } from '@sapper/service-worker'; ...and more for any others in future, not to mention any userland additions (I'll typically have folders like But Ben is right! This discussion has long since outlived its usefulness. No-one has come up with any good alternatives, so I'm going to lock this thread. |
Summarising an earlier conversation from Discord for posterity, for when Svelte 3 is done and the focus can return to Sapper.
A lot of people find it a bit weird (where 'weird' means 'ugly', 'hacky-seeming', 'awkward' or whatever) that you need to import the generated Sapper app from
../__sapper__/client.js
and so on. It's especially bad if you need to import (say)goto
from a deeply nested file —../../../../../
.One solution would be to use aliases in the webpack and Rollup configs. This has a couple of drawbacks:
An alternative idea would be to write the app to
node_modules
inside the app'ssrc
directory — i.e.src/node_modules/app/client.js
and so on:(You'll note I've imported
app
instead ofapp/client.js
andapp/server.js
— I'm wondering if it's possible to have a single module and rely on tree-shaking, or if that would slow down the build too much.)To me this feels like all upside:
node_modules
resolution algorithm, so it wouldn't be surprising behaviourapp
folder to understand how everything works (e.g. what the route manifest looks like)node_modules
is already gitignored, so it's unobtrusiveA few people are a bit sceptical of the idea, and have raised points such as:
../../../../__sapper__/client.js
isn't so badnode_modules
directorynode_modules
directory insrc
app
is the wrong name (what if I wanted to use https://www.npmjs.com/package/app in my Sapper app?!)sapper/runtime.js
and./manifest/client.js
. stop breaking our apps you feckless idiotIt has to be
src/node_modules
and notnode_modules
, since npm and yarn are likely to periodically nuke generated code innode_modules
. I'd argue that's preferable anyway, for the visibility reason stated above.What does everyone think?
The text was updated successfully, but these errors were encountered: