Lit2.0で作成したコンポーネントをStorybookで表示してもSassのスタイルが当たらなかったのでやったことのメモ。
rollupの設定
import resolve from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import typescript from '@rollup/plugin-typescript';
import dts from 'rollup-plugin-dts';
import postcss from 'rollup-plugin-postcss';
const packageJson = require('./package.json');
export default [
{
input: 'src/index.ts',
output: [
{
file: packageJson.main,
format: 'esm',
sourcemap: true,
},
],
plugins: [
resolve(),
commonjs(),
typescript({ tsconfig: './tsconfig.json' }),
postcss({
plugins: [],
}),
],
},
{
input: 'dist/types/index.d.ts',
output: [{ file: 'dist/index.d.ts', format: 'esm' }],
plugins: [dts.default()],
external: [/\.css$/],
},
];
コンポーネントの設定
src/components/SimpleGreeting
import { LitElement, html, unsafeCSS } from 'lit';
import { customElement, property } from 'lit/decorators.js';
import styles from './SimpleGreeting.scss';
@customElement('simple-greeting')
export class SimpleGreeting extends LitElement {
static styles =[unsafeCSS(styles)]
override render() {
return html`<p class="test">Hello!</p>`;
}
}
declare global {
interface HTMLElementTagNameMap {
'simple-greeting': SimpleGreeting;
}
}
src/components/SimpleGreeting/SimpleGreeting.scss
.text {
color: red;
}
src/components/SimpleGreeting/SimpleGreeting.stories.ts
import { html, TemplateResult } from "lit";
import "./SimpleGreeting";
export default {
title: "SimpleGreeting",
component: "simple-greeting",
};
const Template = () => html` <simple-greeting></simple-greeting>`;
export const Regular = Template.bind({});
src/components/SimpleGreeting/index.ts
export { SimpleGreeting } from './SimpleGreeting';
Storybookの設定
.storybook/main.js
const path = require("path");
module.exports = {
stories: ["../src/**/*.stories.mdx", "../src/**/*.stories.@(js|jsx|ts|tsx)"],
addons: [
"@storybook/addon-links",
"@storybook/addon-essentials",
],
framework: "@storybook/web-components",
core: {
builder: "@storybook/builder-webpack5",
},
webpackFinal: async (config) => {
config.module.rules.push({
test: /\.scss$/,
use: [
"style-loader",
{
loader: "css-loader",
options: {
modules: {
auto: true,
},
},
},
"sass-loader",
],
include: path.resolve(__dirname, "../"),
});
return config;
},
};
yarn storybook
でStorybookを起動してテキストが赤になれば良いが黒のまま。
unsafeCSSを使わなければCSSが当たる
- static styles = [unsafeCSS(styles)];
+ static styles = css`
.test {
color: red;
}
`;
stylesのログを出すとundifined
import styles from './SimpleGreeting.scss';
console.log(styles) // output: undifined
SassをCSSに変更してもうまくいかない
- import styles from './SimpleGreeting.scss';
+ import styles from './SimpleGreeting.css';
addonを使ってみてもうまくいかない
Storybook CSS Modules Addon | Storybook: Frontend workshop for UI development
暫定対応としてweb-dev-serverを使う
yarn add -D @web/dev-server
web-dev-server.config.mjs
// import { hmrPlugin, presets } from '@open-wc/dev-server-hmr'
/** Use Hot Module replacement by adding --hmr to the start command */
const hmr = process.argv.includes('--hmr');
export default /** @type {import('@web/dev-server').DevServerConfig} */ ({
open: '/demo/',
/** Use regular watch mode if HMR is not enabled. */
watch: !hmr,
/** Resolve bare module imports */
nodeResolve: {
exportConditions: ['browser', 'development'],
},
/** Compile JS for older browsers. Requires @web/dev-server-esbuild plugin */
// esbuildTarget: 'auto'
/** Set appIndex to enable SPA routing */
// appIndex: 'demo/index.html',
plugins: [
/** Use Hot Module Replacement by uncommenting. Requires @open-wc/dev-server-hmr plugin */
// hmr && hmrPlugin({ exclude: ['**/*/node_modules/**/*'], presets: [presets.litElement] }),
],
// See documentation for all available options
});
package.json
"start": "yarn run build && concurrently -k -r \"yarn run watch\" \"wds\""
demo/index.html
<!DOCTYPE html>
<html lang="en-GB">
<head>
<meta charset="utf-8" />
<style>
body {
background-color: white;
}
</style>
</head>
<body>
<div id="demo"></div>
<script type="module">
import { html, render } from "lit";
import "../dist/index.js";
render(
html`<simple-greeting><simple-greeting />`,
document.querySelector("#demo")
);
</script>
</body>
</html>
Storybookの代わりにHTMLに作成したWeb Componentsを表示して開発を進めてみる
追記
lit-css-loaderを利用するとstorybookでSassのスタイルが表示されました
const Sass = require('sass');
module.exports = {
...
webpackFinal: async (config) => {
config.module.rules.push({
test: /\.scss$/,
loader: 'lit-css-loader',
options: {
transform: (data, { filePath }) =>
Sass.renderSync({ data, file: filePath })
.css.toString(),
}
});
return config;
}
}