- Start Date: 2020-05-21
- RFC PR: (leave this empty)
- Svelte Issue: (leave this empty)
Place Sapper configuration in a .config.js
file
There are a number of PRs or open issues for the Sapper project that would require providing a configuration option. We should handle configuration in a well-thought out and consistent manner. Deciding this would unblock review on a large number of Sapper PRs.
language-tools already uses a svelte.config.js
and Svelte core was considering adopting it more widely.
- sveltejs/sapper#1215
- sveltejs/sapper#1001
- sveltejs/sapper#1001
- sveltejs/sapper#994
- sveltejs/sapper#984
- sveltejs/sapper#960
- sveltejs/sapper#953
- sveltejs/sapper#1152 / sveltejs/sapper#1037 (stick user-provided functions on
result
in a middleware)
- sveltejs/sapper#1075
- sveltejs/sapper#1021
- sveltejs/sapper#1020
- sveltejs/sapper#932
- sveltejs/sapper#866
- sveltejs/sapper#859
- sveltejs/sapper#856
- sveltejs/sapper#813
We would use a .config.js
because it's inline with the existing svelte.config.js
used by language-tools
and also because it's more flexible. For instance, it allows
providing types that could not be specified in YAML such as function
.
The configuration file should be completely optional with sensible defaults.
I propose a sapper.config.js
file with the following structure:
{
bundler, // Specify a bundler (rollup or webpack, blank for auto)
cwd, // Current working directory (default .)
ext, // Custom Route Extension (default .svelte .html)
legacy, // Create separate legacy build
output, // Sapper intermediate file output directory (default src/node_modules/@sapper)
port, // Default of process.env.PORT (default 3000)
routes, // Routes directory (default src/routes)
src, // Source directory (default src)
middleware: {
ignore // Requests to ignore. Array | RegExp | function |
session // Session creation function. (req: Req, res: Res) => any
},
dev: {
buildDir, // Development build directory (default __sapper__/dev)
devPort, // Specify a port for development server
hot, // Use hot module replacement (requires webpack) (default true)
live, // Reload on changes if not using --hot (default true)
open, // Open a browser window
port, // Specify a port
static, // Static files directory (default static)
},
export: {
basepath, // Specify a base path
build, // (Re)build app before exporting (default true)
buildDir, // Intermediate build directory (default __sapper__/build)
concurrent, // Concurrent requests (default 8)
entry, // Custom entry points (space separated) (default /)
host, // Host header to use when crawling site
timeout, // Milliseconds to wait for a page (--no-timeout to disable) (default 5000)
}
}
The initial implementation would not concern the client-side application. Only one of the pending PRs touched client-side config. It could easily be extended to include client configuration in the future, however.
There should be a consistent precedence hierarchy.
For the CLI tool:
- flags
- env vars
- global config
- config namespaced to CLI command (
build
,dev
, orexport
) - default value
CLI flags would be converted from dashed option-name
to camelcase optionName
.
ENV vars would be converted from capitalized OPTION_NAME
to camelcase optionName
.
For the middleware:
- options argument in middleware constructor
middleware
configuration- default value
Flags and environment variables may be able to be supported in the middleware for simple values in the future. However, the two existing options are both functions, which could not be specified in this manner and so there currently is not a need to support this.
This feature would be relatively easy to teach. We would update the Sapper docs and template projects. Putting all configuration in a single place would improve teachability over the current state. The proposal is backwards compatible, which reduces education needs.
It's possibly yet another configuration file in people's projects depending on implementation.
There would now be multiple places configuration could be specified. That may confuse some new users.
It may become a harder to make changes to expected configuration if external tools are using the file format.
We could continue to specify options only as objects in the middleware constructor and command line flags for the CLI tool like we're doing today. There are a few drawbacks with doing this.
There are many options such as the location of the source directory that must be
specified with each CLI command. It can become complicated to provide a long-list
of command line flags. Users will end up creating shell scripts to save their
configuration. Shell scripts are not as easily maintained as .config.js
for most
JavaScript develoeprs.
Also, sharing with other tools is harder. Configuration that's in a standardized
location in a .config.js
can easily be read by multiple tools and libraries.
Prettier reported
that putting off creation of a config file meant tools developed their own incompatible
methods for dealing with these question, which became a net negative.
- Should Sapper's config go inside
svelte.config.js
under asapper
namespace or be a newsapper.config.js
file?- There may be some config like the
legacy
option which is used by both tools. I don't know if Sapper does anything special with this today or it's just a straight passthrough to Svelte, but you could imagine Sapper doing extra work if this flag was detected. You probably don't want to have to set it twice. Should Sapper just defer to asvelte.config.js
for this value or should we combine the files?
- There may be some config like the
- Do we want all middleware configuration to be able to be provided by the
.config.js
?- It's a little awkward to specify a function taking a request and response in the config file if you're using TypeScript because you would need to import those types. It also just doesn't seem like where it should be done. Still it seems better for consistency that we allow all options to be specified that way. It makes it easier to understand for users and easier to implement. Users can simply provide the options via middleware constructor instead of config file for the ones where they prefer to do that