You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
A permutation is a way to build multiples variants of the same Svelte application, according to various criteria.
A permutations will have an impact on the generated code by allowing certain files to be 'replaced' by others at build time.
This will allow to have a common codebase for multiple target, each of which could have its own specificities, like dedicated CSS/components/code/ressources/pages...
Some use-case :
Sites for different audiences.
Sites for different localisations.
Sites for different clients, with specific template/customisation.
Describe the proposed solution
Permutations keys
Permutations would be defined by custom keys and their values, declared on the svelte.config.js
/// svelte.config.jspermutations: {keys: {/* any records as name: string[] */}},
Permutation keys will be project-specific key/values that define variants of our project.
For example, if we want to use a common project to build 3 specifics site/app for our customers (b2c), our partners (b2b), and our internal teams (int), we could define something like this :
And all npm run command will use the first-permutation ('b2c,en' in the current case) :
# Launch dev mode for permutation 'b2c,en' (default)
npm run dev
But we might use a flag to select another permutation, for example --perm :
# Launch dev mode for permutation 'b2c' in 'fr' (explicitly)
npm run dev --perm b2c,fr
# Launch dev mode for permutation 'int' in 'it' (explicitly)
npm run dev --perm int,it
Special case : the check and build task will accept an --all-perms flag to check/build all the permutations :
# Launch check for all permutations
npm run check --all-perms
# Launch build for all permutations
npm run build --all-perms
Permutations files
All files of the project will accept a permutation rules in order to choose the more specific file.
This could be represented by a mark as an extension suffix like .(permutations), juste before the real file extension.
For example for the logical file mycode.js, we can have :
mycode.(b2c,en).js which represents the file for the 'b2c,en' permutation.
mycode.(b2c).js which represents the file for any of the 'b2c' permutations.
mycode.(en).js which represents the file for any of the 'en' permutations.
mycode.js which represents the default file, when any other match.
By using unique permutation name and some naming convention, we can even make more precise targeting.
Ex:
mycode.(b2c,b2b).js represents all the permutations with target 'b2c' or 'b2b'.
mycode.(b2c,b2b,en).js represents all the permutations with target 'b2c' or 'b2b', AND the lang 'en'.
mycode.(-int).js represents all the permutations where target is NOT 'int'
Import file
The permutation should work when we import a file, for example :
For permutation 'b2c,en', it will use Header.(b2c).svelte, Footer.(b2c).svelte, messages.(en).js and styles.(b2c).css
For permutation 'b2c,fr', it will use Header.(b2c).svelte, Footer.(b2c,fr).svelte, messages.(fr).js and styles.(b2c).css
For permutation 'b2b,en', it will use Header.(b2b).svelte, Footer.svelte, messages.(en).js and styles.(b2b).css
For permutation 'b2b,fr', it will use Header.(b2b).svelte, Footer.(fr).svelte, messages.(fr).js and styles.(b2b).css
...
The compiler should produce an error if the permutation mark is used on import :
// ERROR : invalid import with a permutation mark// Should use 'Header.svelte' insteadimportHeaderfrom'Header.(b2c).svelte';
Static file
The same rule should apply to the static file.
For example in order to have distinct favicons :
When serving/building the apps, the file will be renamed with his base name.
Routing
The svelte routing files (+page, +layout, +server) should follow the same rule, with one exception : a missing permutation will not throw an error, but simply consider that the file does not exist.
The 'stuff' page will be present on all permutations.
The 'news' page will be present on all permutations, but the 'int' permutations will use a specific template.
The 'contact' page will only be present on 'b2c' and 'b2b' permutations, with a specific template for each target.
The 'about' page only be present on 'b2c' and 'b2b' permutations, with a specific template for the 'b2c,fr' permutation.
Each target ('b2c', 'b2b' and 'int') will use a specific layout template.
Permutations directories
Another solution will be to use a permutation directory for src and static.
For example :
src/ # Will contains code shared by all permutations.
src.(b2c)/ # Will contains code for 'b2c' permutation.
static/ # Will contains static file for all permutations.
static.(b2c)/ # Will contains static file for 'b2c' permutation.
Perhaps we can event use both, so :
import Component from '$lib/Component.svelte';
For the b2c,en permutation, it will return the first file found in this order :
src.(b2c)/lib/Component.(en).svelte or src/lib/Component.(b2c,en).svelte
src.(b2c)/lib/Component.svelte or src/lib/Component.(b2c).svelte
src.(en)/lib/Component.svelte or src/lib/Component.(en).svelte
src/lib/Component.svelte
By generating an error in case of duplicate file at the same level.
Server side processing
The handle() hook in hooks.server.js|ts will receive a new property 'permutation'.
This property will be a object representing the current permutation configuration.
For example, for the b2c,en permutation, this will match an object of the following form :
{target: 'b2c',lang: 'en'}
Build mode
The build mode will define the way that Sveltekit will build the apps.
I see two main build mode.
In 'distinct' build mode, Sveltekit wil produce a distinct build for each permutation.
This is the default behavior described since the beginning of this document.
It should be compatible with all current adapters.
We just need to specify the build we want to dev/build on the npm run commands.
In ‘bundle’ build mode, Sveltekit wil produce a common build for all the permutations.
This build will include all the permutation code, and will generate an app.js for each permutation, with it's own dictionary.
The server will serve the correct client code based on the request.
Obviously this mode will be incompatible with some adapters without server-side code (like adapter-static)
In order to do that, it will require a mapping property that define all the mapping between the URL and the permutations.
In case of null/incorrect permutation name, the server will return an error.
And in this case we can use the handle() to redirect to the best domain...
The ‘group’ build mode is an intermediate version.
Sveltekit will generate distinct build based on the specified group_keys, which will bundle the other permutation keys.
In this example, using group_keys: ['target'] will generation 3 main permutations :
b2c that bundle b2c,en, b2c,fr, b2c.de and b2c.it
b2b that bundle b2b,en, b2b,fr, b2b.de and b2b.it
int that bundle int,en, int,fr, int.de and int.it
Alternatives considered
No response
Importance
nice to have
Additional Information
No response
The text was updated successfully, but these errors were encountered:
Describe the problem
Concept
A permutation is a way to build multiples variants of the same Svelte application, according to various criteria.
A permutations will have an impact on the generated code by allowing certain files to be 'replaced' by others at build time.
This will allow to have a common codebase for multiple target, each of which could have its own specificities, like dedicated CSS/components/code/ressources/pages...
Some use-case :
Describe the proposed solution
Permutations keys
Permutations would be defined by custom keys and their values, declared on the
svelte.config.js
Permutation keys will be project-specific key/values that define variants of our project.
For example, if we want to use a common project to build 3 specifics site/app for our customers (b2c), our partners (b2b), and our internal teams (int), we could define something like this :
And if, in addition to that, we want to generate 4 differents languages ('en', 'fr', 'de', 'it'), we could use :
We have now 3 targets variants in 4 differents langs, which will produce 12 distincts permutations builds :
By default, each build will have his own subdirectory in the svelte-kit folder :
And all
npm run
command will use the first-permutation ('b2c,en' in the current case) :# Launch dev mode for permutation 'b2c,en' (default) npm run dev
But we might use a flag to select another permutation, for example
--perm
:Special case : the
check
andbuild
task will accept an--all-perms
flag to check/build all the permutations :Permutations files
All files of the project will accept a permutation rules in order to choose the more specific file.
This could be represented by a mark as an extension suffix like
.(permutations)
, juste before the real file extension.For example for the logical file
mycode.js
, we can have :mycode.(b2c,en).js
which represents the file for the 'b2c,en' permutation.mycode.(b2c).js
which represents the file for any of the 'b2c' permutations.mycode.(en).js
which represents the file for any of the 'en' permutations.mycode.js
which represents the default file, when any other match.By using unique permutation name and some naming convention, we can even make more precise targeting.
Ex:
mycode.(b2c,b2b).js
represents all the permutations with target 'b2c' or 'b2b'.mycode.(b2c,b2b,en).js
represents all the permutations with target 'b2c' or 'b2b', AND the lang 'en'.mycode.(-int).js
represents all the permutations where target is NOT 'int'Import file
The permutation should work when we import a file, for example :
The importeds files will depends from the current permutation and the permutations rules of the file's variants.
For example, if we have theses files :
For permutation 'b2c,en', it will use
Header.(b2c).svelte
,Footer.(b2c).svelte
,messages.(en).js
andstyles.(b2c).css
For permutation 'b2c,fr', it will use
Header.(b2c).svelte
,Footer.(b2c,fr).svelte
,messages.(fr).js
andstyles.(b2c).css
For permutation 'b2b,en', it will use
Header.(b2b).svelte
,Footer.svelte
,messages.(en).js
andstyles.(b2b).css
For permutation 'b2b,fr', it will use
Header.(b2b).svelte
,Footer.(fr).svelte
,messages.(fr).js
andstyles.(b2b).css
...
The compiler should produce an error if the permutation mark is used on import :
Static file
The same rule should apply to the static file.
For example in order to have distinct favicons :
When serving/building the apps, the file will be renamed with his base name.
Routing
The svelte routing files (+page, +layout, +server) should follow the same rule, with one exception : a missing permutation will not throw an error, but simply consider that the file does not exist.
Example, with this with this route tree :
Permutations directories
Another solution will be to use a permutation directory for
src
andstatic
.For example :
Perhaps we can event use both, so :
For the
b2c,en
permutation, it will return the first file found in this order :src.(b2c)/lib/Component.(en).svelte
orsrc/lib/Component.(b2c,en).svelte
src.(b2c)/lib/Component.svelte
orsrc/lib/Component.(b2c).svelte
src.(en)/lib/Component.svelte
orsrc/lib/Component.(en).svelte
src/lib/Component.svelte
By generating an error in case of duplicate file at the same level.
Server side processing
The
handle()
hook inhooks.server.js|ts
will receive a new property 'permutation'.This property will be a object representing the current permutation configuration.
For example, for the
b2c,en
permutation, this will match an object of the following form :Build mode
The build mode will define the way that Sveltekit will build the apps.
I see two main build mode.
build: 'distinct'
In 'distinct' build mode, Sveltekit wil produce a distinct build for each permutation.
This is the default behavior described since the beginning of this document.
It should be compatible with all current adapters.
We just need to specify the build we want to dev/build on the
npm run
commands.build: 'bundle'
In ‘bundle’ build mode, Sveltekit wil produce a common build for all the permutations.
This build will include all the permutation code, and will generate an
app.js
for each permutation, with it's own dictionary.The server will serve the correct client code based on the request.
Obviously this mode will be incompatible with some adapters without server-side code (like adapter-static)
In order to do that, it will require a
mapping
property that define all the mapping between the URL and the permutations.For example :
Here
www.my-site.com
will serve the 'b2c,en' permutation,www.my-site.fr
will serve 'b2c,fr', and so on...We can also imagine a
mapping_dev
allowing to use different domain for dev mode.An alternative/complement would be to use a server hook for that, allowing us to handle more special case :
In case of null/incorrect permutation name, the server will return an error.
And in this case we can use the
handle()
to redirect to the best domain...build: 'group'
The ‘group’ build mode is an intermediate version.
Sveltekit will generate distinct build based on the specified group_keys, which will bundle the other permutation keys.
In this example, using
group_keys: ['target']
will generation 3 main permutations :b2c
that bundleb2c,en
,b2c,fr
,b2c.de
andb2c.it
b2b
that bundleb2b,en
,b2b,fr
,b2b.de
andb2b.it
int
that bundleint,en
,int,fr
,int.de
andint.it
Alternatives considered
No response
Importance
nice to have
Additional Information
No response
The text was updated successfully, but these errors were encountered: