-
-
Notifications
You must be signed in to change notification settings - Fork 832
Description
(please note - this is a live document. I'm adding more things as I work on them)
Over the past couple of months I've been working hard getting Stencil core into a better place; squashing lots of long-standing, annoying bugs (this is continuing) plus adding long .... long requested features that Stencil should have had earlier (extends, Mixin, @Prop get / set, runtime custom @Decorators to name a few).
As I look to v5 I'm looking at consolidation, organisation and deprecation - this will include breaking changes.
Stencil has always been pretty stable when it comes to it's API.
Whilst this is nice from a upgrade POV it has come at the cost of technical debt - Stencil recently had it's 10th birthday 🎂 - 10 years worth of technical debt!
In this issue I want to publicly make known what is currently just in my head (or actively being worked on) and let's discuss it here.
BREAKING CHANGE - Integrated testing removal
Back in the days of 2016, setting up testing for front-end things was hard. The original authors wanted a first class, seamless testing experience which involved a hard-coupling with a custom Jest runner and environment, in combination with a custom Puppeteer setup.
This coupling has hamstrung Stencil core and it's users in many ways.
- Stencil core needs to offer a different, custom Jest setup for every major version of Jest. When this became too burdensome to maintain, users became locked to Jest v291
- Stencil's
--spectests do a 'compile lite' on-the-fly for a given component class, then bootstrap it in Stencil's integrated node-dom -MockDoc. This whole process is increasingly problematic:- it reaches into Stencil's internals to work which is prone to error and is fundamentally not representative of the final output.
- is very difficult to make work with classes that can now use
extends(optionally in combination with Mixin) - doesn't give devs the option to use their 'node dom' of choice (e.g. happy-dom, JSDOM)
- Stencil's
--e2etests are hard baked to use Puppeteer which doesn't have the same DevX around browser testing as newer options like Cypress and Playwright.
Migration pathway
- For
--specstyle tests, migrate to using https://github.com/stenciljs/vitest. It has a similar API to the current Jest integration but gives devs far greater control. Test against different bundles / outputs, test in a real browser (a11y tests, visual regressions etc), or pick your node-dom of choice. - For
--e2estyle tests I would probably say that many library authors actually want 'component' tests - isolated testing of their components that just happen to run in a browser - again - use https://github.com/stenciljs/vitest. For those cases where actual e2e tests are required (routing, full applications, proper onload initialisation) use https://github.com/stenciljs/playwright
BREAKING CHANGE - @Component API
The @Component API is convoluted and not very amenable to updates or changes.
Current
interface ComponentConfig {
tag: string;
formAssociated?: boolean;
/* don't use shadowDOM < use scoped classes instead */
scoped?: boolean;
/* use shadowDOM if true ... use nothing if false. Or you can omit to use nothing // then you can also have scoped */
shadow?: boolean | {
delegatesFocus?: boolean, slotAssignment?: 'manual' | 'named'
}
// .. some other things around styling / assets that make sense //
}Proposed
interface ComponentConfig {
tag: string;
encapsulation?:
| { type: 'shadow'; mode?: 'open' | 'closed'; delegatesFocus?: boolean; slotAssignment?: 'manual' | 'named' }
| { type: 'none'; patches?: ('all' | 'children' | 'clone' | 'insert')[] }
| { type: 'scoped'; patches?: ('all' | 'children' | 'clone' | 'insert')[] };
// ^ nb - these patches can be applied globally via `config.extras` as they now
// other unrelated config
}Whilst this is slightly more verbose I think it's much clearer around intent plus much easier to add more options in future. Feedback welcome.
formAssociation will move into the @AttachInternals decorator options
Migration pathway
A new stencil migrate CLI option will be added to update from old > new
BREAKING CHANGE - CommonJS
Stencil itself will migrate it's compiled source to ESM.
Proposed
Removal of all CJS outputs or at least - will become an extra opt-in or configuration option.
BREAKING CHANGE - ES5 / Polyfills removal
Removal of all options around old polyfills / shims and ES5, 'system' modules
BREAKING CHANGE - config.extras
There are a bunch of old / deprecated options that are or will be flagged as deprecated and removed in V5.
BREAKING CHANGE - internal structure
Many internal paths will be moved / renamed / become their own packages
@stencil/core/internal→@stencil/core/runtime@stencil/core/internal/client→@stencil/core/runtime/client@stencil/core/internal/hydrate→@stencil/core/runtime/server@stencil/core/cli→@stencil/cli@stencil/core/dev-server→@stencil/dev-server@stencil/core/mock-doc→@stencil/mock-doc
BREAKING CHANGE - openBrowser
The dev-server will no longer open the browser by default.
Migration pathway
- No need to pass in
--no-openanymore. - Pass in
--open(in the cli) oropenBrowserto thedevServerconfig options, for previous auto-open behaviour
BREAKING CHANGE - @Watch initialisation
The documentation around Stencil's lifecycle (https://stenciljs.com/docs/component-lifecycle#component-lifecycle-methods) is quite clear; watchers should, by default, not fire until the component has been fully rendered. At present - especially within the dist output, watch methods can be called during every lifecycle stage.
In v5 @Watch methods adhere to the documentation. Whilst this is strictly a fix, the current behaviour is so long-standing users may have started to rely on it.
Migration pathway
If you need to call watch methods before the component is completely ready, manually them within lifecycle methods.
Alternatively, use the immediate flag - @Watch({ immediate: true }).
More TBD
This is a live document ... I'm adding more things as I work on them