-
Notifications
You must be signed in to change notification settings - Fork 320
Closed
Description
I'm new to lit-element and I'm trying to implement a custom element for rendering math equations for my website using Katex.
To properly render the equations, I need to import the css&font files provided by Katex.
I have the following codes,
import styles from '!!raw-loader!katex/dist/katex.css'
// Some font files are imported inside the katex.css files, so this line won't work. (The font files won't be processed by webpack.
import 'katex/dist/katex.css'
//So I add `import 'katex/dist/katex.css'` as well.
...
static get styles() {
return [unsafeCSS(styles)]
}
...
it works but there are still some problems.
- the same code will be imported twice
- the font import statement inside
unsafeCSS(styles)will be executed, but the path is not correct.
So my goal is two: 1. let weback recursively process all styles related files 2. get the CSS string so I can use it with unsafeCSS(styles)
below are the complete code and my webpack config.
import { LitElement, html, property, customElement, unsafeCSS } from 'lit-element'
import { unsafeHTML } from 'lit-html/directives/unsafe-html.js'
import { styleMap } from 'lit-html/directives/style-map'
import katex from 'katex'
import 'katex/dist/katex.css'
import styles from '!!raw-loader!katex/dist/katex.css'
@customElement('mathjax-panel')
export class MathjaxPanel extends LitElement {
@property() rendered = ''
@property({ reflect: true }) block = false
static get styles() {
return [unsafeCSS(styles)]
}
slotchange = (event: Event) => {
const slot = this.shadowRoot?.querySelector('slot')
const math = slot?.assignedNodes()[0].textContent
if (math) {
try {
this.rendered = katex.renderToString(math, { displayMode: this.block, output: 'html' })
} catch (error) {
console.error(`failed to render math equation: ${math}`)
}
}
}
render() {
const rstyle = this.rendered ? '' : styleMap({ display: 'none' })
const pstyle = this.rendered ? styleMap({ display: 'none' }) : ''
if (this.block) {
return html`
<div style=${rstyle}>${unsafeHTML(this.rendered)}</div>
<pre style=${pstyle}><div><slot @slotchange=${this.slotchange}></slot></div></pre>
`
}
return html`
<span style=${rstyle}>${unsafeHTML(this.rendered)}</span>
<pre style=${pstyle}><span><slot @slotchange=${this.slotchange}></slot></span></pre>
`
}
}
webpack.common.js:
const paths = require('./paths')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const configs = {
entry: './src/app.ts',
devtool: 'inline-source-map',
output: {
publicPath: '/web/static',
},
module: {
rules: [
{
test: /\.tsx?$/,
use: 'ts-loader',
exclude: /node_modules/,
},
{
test: /\.(png|svg|jpg|gif)$/,
use: ['file-loader'],
},
{
test: /\.(woff|woff2|eot|ttf|otf)$/,
use: [
{
loader: 'file-loader',
options: {
name: '[name].[ext]',
outputPath: 'fonts/'
}
}
]
},
],
},
resolve: {
extensions: ['.tsx', '.ts', '.js'],
},
output: {
filename: '[name].bundle.js',
path: paths.pages_dir,
},
}
module.exports = configs
webpack.dev.js:
const { merge } = require('webpack-merge');
const common = require('./webpack.common.js')
module.exports = merge(common, {
mode: 'development', devtool: 'inline-source-map', module: {
rules: [
{
test: /\.css$/,
use: ['style-loader', 'css-loader'],
},
],
},
})
webpack.prod.js:
const { merge } = require('webpack-merge');
const common = require('./webpack.common.js')
const TerserJSPlugin = require('terser-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
module.exports = merge(common, {
mode: 'production', devtool: 'source-map', module: {
rules: [
{
test: /\.css$/i,
use: [MiniCssExtractPlugin.loader, 'css-loader'],
},
],
},
plugins: [new MiniCssExtractPlugin()],
optimization: {
minimize: true,
minimizer: [new TerserJSPlugin({}), new CssMinimizerPlugin()],
},
})
israelfloresdga