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:
- it hides important implementation details, making it harder for someone coming to the project to understand where the app is 'coming from'
- it adds further complexity to the build configs, increasing maintenance burden (e.g. if we were to add support for Parcel etc)
An alternative idea would be to write the app to node_modules
inside the app's src
directory — i.e. src/node_modules/app/client.js
and so on:
// src/client.js
-import * as sapper from '../__sapper__/client.js';
+import * as app from 'app';
-sapper.start({
+app.start({
target: document.querySelector('#sapper')
});
// src/server.js
import sirv from 'sirv';
import polka from 'polka';
import compression from 'compression';
-import * as sapper from '../__sapper__/server.js';
+import * as app from 'app';
const { PORT, NODE_ENV } = process.env;
const dev = NODE_ENV === 'development';
polka() // You can also use Express
.use(
compression({ threshold: 0 }),
sirv('static', { dev }),
- sapper.middleware()
+ app.middleware()
)
.listen(PORT, err => {
if (err) console.log('error', err);
});
(You'll note I've imported app
instead of app/client.js
and app/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:
- it's very easy to type, and reinforces the idea that 'app' is a singleton that is bespokely generated for you
- everybody pretty much intuitively understands the
node_modules
resolution algorithm, so it wouldn't be surprising behaviour
- it's visible — you can see where your app is coming from, and can read the generated source code in the
app
folder to understand how everything works (e.g. what the route manifest looks like)
node_modules
is already gitignored, so it's unobtrusive
A few people are a bit sceptical of the idea, and have raised points such as:
- maybe
../../../../__sapper__/client.js
isn't so bad
- it's weird to put generated code in a
node_modules
directory
- it's weird to put a
node_modules
directory in src
- maybe
app
is the wrong name (what if I wanted to use https://www.npmjs.com/package/app in my Sapper app?!)
- dammit Rich, we only just changed it from
sapper/runtime.js
and ./manifest/client.js
. stop breaking our apps you feckless idiot
It has to be src/node_modules
and not node_modules
, since npm and yarn are likely to periodically nuke generated code in node_modules
. I'd argue that's preferable anyway, for the visibility reason stated above.
What does everyone think?