Not really a bug, just something that someone may come across and the solution (where "someone" will probably be me in 6+ months time ...)
A template exported from a project that is symlinked doesn't render properly bundled using rollup.
Not appropriate
Suppose you have an "elements" project where you work on UI components independently. Inside it, you export a template, maybe a sharedStyles template that you also want to re-use in application view elements. Something like:
import { html } from "lit-html"
export const sharedStyles = html`
<style>
:host {
display: block;
box-sizing: border-box;
}
:host([hidden]), [hidden] {
display: none !important;
}
</style>`
While developing, you don't want to keep publishing to npm just to use them in the consuming app project so you use a symlink or npm link to reference the elements project from the app.
Inside the app, you import the exported template and use it in an element:
import { sharedStyles } from '@privatenpmscope/my-elements/shared-styles';
...
render() {
return html`
${sharedStyles}
You bundle the app using rollup
sharedStyles renders HTML output on the page
sharedStyles renders as [object Object] because rollup includes some parts of lit-html twice, even if you de-dupe things (todo with path resolution).
If you come across this, the solution is to set the preserveSymlinks option in rollup to true, this can be set as a command line option (rollup -c --preserveSymlinks) or added to rollup.config.js:
'use strict';
import resolve from 'rollup-plugin-node-resolve';
import commonjs from 'rollup-plugin-commonjs';
import replace from 'rollup-plugin-replace';
import minifyHTML from 'rollup-plugin-minify-html-literals';
import typescript from 'rollup-plugin-typescript';
import { terser } from 'rollup-plugin-terser';
// assume production mode for normal build, dev if watched
// flag is used to enable / disable HTML & JS minification
const production = !process.env.ROLLUP_WATCH;
export default {
input: 'src/index.ts',
output: {
file: 'dist/scripts/myapp.min.js',
format: 'iife',
sourcemap: true,
},
plugins: [
replace({
'process.env.NODE_ENV': JSON.stringify('production')
}),
resolve(),
commonjs(),
production && minifyHTML(),
typescript({ typescript: require('typescript') }),
production && terser(),
],
preserveSymlinks: true,
}
Thanks for pointing this out. Marked it for inclusion in the docs.
Also worth noting, if anyone is experiencing this issue or the related one where the JS code for a directive is being rendered instead of its results, it's usually caused by having more than one copy of lit-html being bundled.
One way to check is to look at the sourcemap to see if there are multiple entries for lit-html and it will also indicate where they are coming from, e.g.
"sources: [
"../../node_modules/lit-html/lit-html.js",
"../../../some-included-elements/node_modules/lit-html/lit-html.js",
...
]
Ran into this issue today using webpack. Here was my solution:
resolve: {
alias: {
"lit-element": path.resolve("./node_modules/lit-element")
}
}
We have lit-html issues opened for this.
When consuming typed mixins that rely on lit-element (https://github.com/anoblet/mixins/blob/master/src/BeforeRender.ts) I've encountered similar errors (lit-element !=== lit-element). The solution for the consuming package with typescript was:
{
"compilerOptions": {
"paths": {
"lit-element": ["node_modules/lit-element"],
"lit-html": ["node_modules/lit-html"]
}
}
}
We have lit-html issues opened for this.
@justinfagnani - Which issue ?
This is closed and can't find anything similar
Most helpful comment
Ran into this issue today using webpack. Here was my solution: