Skip to content

Commit 02b8d62

Browse files
[lit-html] Add dev mode warning when static values are detected in non static templates (#4345)
Co-authored-by: Augustine Kim <augustinekim@google.com>
1 parent 62d7818 commit 02b8d62

3 files changed

Lines changed: 40 additions & 0 deletions

File tree

.changeset/six-planets-notice.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
'lit': patch
3+
'lit-html': patch
4+
---
5+
6+
Add a dev mode warning if a static value such as `literal` or `unsafeStatic` is detected within the non-static `html` tag function. These should only be used with the static `html` tag function imported from `lit-html/static.js` or `lit/static-html.js`.

packages/lit-html/src/lit-html.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -511,6 +511,20 @@ const tag =
511511
'This is probably caused by illegal octal escape sequences.'
512512
);
513513
}
514+
if (DEV_MODE) {
515+
// Import static-html.js results in a circular dependency which g3 doesn't
516+
// handle. Instead we know that static values must have the field
517+
// `_$litStatic$`.
518+
if (
519+
values.some((val) => (val as {_$litStatic$: unknown})?.['_$litStatic$'])
520+
) {
521+
issueWarning(
522+
'',
523+
`Static values 'literal' or 'unsafeStatic' cannot be used as values to non-static templates.\n` +
524+
`Please use the static 'html' tag function. See https://lit.dev/docs/templates/expressions/#static-expressions`
525+
);
526+
}
527+
}
514528
return {
515529
// This property needs to remain unminified.
516530
['_$litType$']: type,

packages/lit-html/src/test/lit-html_test.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import {
2626
PartInfo,
2727
DirectiveParameters,
2828
} from 'lit-html/directive.js';
29+
import {isCompiledTemplateResult} from 'lit-html/directive-helpers.js';
2930
import {assert} from '@esm-bundle/chai';
3031
import {
3132
stripExpressionComments,
@@ -35,6 +36,7 @@ import {repeat} from 'lit-html/directives/repeat.js';
3536
import {AsyncDirective} from 'lit-html/async-directive.js';
3637

3738
import {createRef, ref} from 'lit-html/directives/ref.js';
39+
import {literal, unsafeStatic} from 'lit-html/static.js';
3840

3941
// For compiled template tests
4042
import {_$LH} from 'lit-html/private-ssr-support.js';
@@ -48,6 +50,10 @@ const isIe = ua.indexOf('Trident/') > 0;
4850
// We don't have direct access to DEV_MODE, but this is a good enough
4951
// proxy.
5052
const DEV_MODE = render.setSanitizer != null;
53+
// Tests are compiled if the passed in runtime template has been
54+
// compiled.
55+
const testAreCompiled = isCompiledTemplateResult(html``);
56+
const skipTestIfCompiled = testAreCompiled ? test.skip : test;
5157

5258
class FireEventDirective extends Directive {
5359
render() {
@@ -3246,5 +3252,19 @@ suite('lit-html', () => {
32463252
);
32473253
assertNoWarning();
32483254
});
3255+
3256+
skipTestIfCompiled(
3257+
'Static values warn if detected without static html tag',
3258+
() => {
3259+
html`${literal`<p>Hello</p>`}`;
3260+
assertWarning('static');
3261+
3262+
html`<div>${unsafeStatic('<p>Hello</p>')}</div>`;
3263+
assertWarning('static');
3264+
3265+
html`<h1 attribute="${unsafeStatic('test')}"></h1>`;
3266+
assertWarning('static');
3267+
}
3268+
);
32493269
});
32503270
});

0 commit comments

Comments
 (0)