Description
#586 and #603 highlight an interesting question. If a component nests another component that was compiled with a previous version of Svelte...
<Widget/>
<script>
// node_modules/some-component-library/[pkg.main].js is precompiled
import { Widget } from 'some-component-library';
export default {
components: { Widget }
};
</script>
...it's more likely that changed internal implementation details (that are not considered, rightly or wrongly, part of the public API) will result in breakage.
At the same time, using precompiled components prevents us from sharing code effectively, resulting in larger bundles with functions that take longer to warm up.
So while it's certainly useful for some-component-library
to ship precompiled components so that people can do this in non-Svelte apps...
import { Widget } from 'some-component-library';
const widget = new Widget({
target: document.querySelector('.widget-container')
});
...it would be great if bundler plugins could avoid precompiled code where possible.
Proposal: pkg.svelte
Suppose the author of some-component-library
included the following in her package.json:
{
"main": "dist/some-component-library.umd.js",
"module": "dist/some-component-library.esm.js",
"svelte": "src/index.js",
...
}
A module-aware bundler (e.g. Rollup or Webpack) would import the pkg.module
, a bundler like Browserify would import pkg.main
.
But an app that was already using Svelte could import pkg.svelte
, and any components re-exported from index.js
would be compiled by the app's build process. This would be trivial to implement in rollup-plugin-svelte (just need to add a resolveId
hook), and I assume it's possible in svelte-loader.
We could also resolve imports like this...
// resolves to node_modules/some-component-library/src/Widget.html
import Widget from 'some-component-library/Widget.html';
...by adding a "svelte.root": "src"
property, analogous to "modules.root"
in this document. (If the app author imported some-component-library/src/Widget.html
directly, it would still work, assuming that the resolution logic saw that src/src/Widget.html
didn't exist and fell back to not using pkg['svelte.root']
.
Breaking changes
This wouldn't eliminate the possibility of breaking changes causing havoc — if a Svelte 3 app imported a Svelte 1 component which contained some long-since-deprecated syntax, the compilation would fail. But it gives us the opportunity to anticipate that breakage (the bundler plugin could compare the versions of Svelte that the app and the imported component depended on) and handle it at compile time with a helpful error message, rather than at runtime with a cryptic one.
Does this sound like a good idea? Is there anything obvious that I'm overlooking?