【发布时间】:2020-06-24 19:42:00
【问题描述】:
我正在尝试修改使用 shadow root 创建的 Web 组件的样式。
我看到样式被添加到head 标签,但它对shadow root 没有影响,因为它是封装的。
我需要加载所有组件的样式并让它们出现在shadow root 的内部。
这是创建 Web 组件的一部分:
index.tsx
import React from 'react';
import ReactDOM from 'react-dom';
import { App } from './App';
import './tmp/mockComponent.css'; // This is the styling i wish to inject
let container: HTMLElement;
class AssetsWebComponent extends HTMLElement {
constructor() {
super();
this.attachShadow({ mode: 'open' });
const { shadowRoot } = this;
container = document.createElement('div');
shadowRoot.appendChild(container);
ReactDOM.render(<App />, container);
}
}
window.customElements.define('assets-component', AssetsWebComponent);
App.ts // 常规反应组件
import React from 'react';
import './App.css';
import { MockComponent } from './tmp/mockComponent'
export const App: React.FunctionComponent = (props) => {
return (
<MockComponent />
);
};
webpack.config.ts
// @ts-ignore
const path = require('path');
const common = require('./webpack.common.ts');
const merge = require('webpack-merge');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = merge(common, {
mode: 'development',
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, 'dist'),
},
module: {
rules: [
{
test: /\.css$/,
use: [
{
loader: 'style-loader',
options: {
insert: function (element) {
const parent = document.querySelector('assets-component');
***This what i want, to inject inside the shadowRoot but it
never steps inside since the shadowRoot not created yet***
if (parent.shadowRoot) {
parent.shadowRoot.appendChild(element);
}
parent.appendChild(element);
},
},
},
'css-loader',
],
},
{
test: /\.scss$/,
use: [
'style-loader',
'css-loader',
'sass-loader',
],
},
],
},
plugins: [
new HtmlWebpackPlugin({
template: './src/template.html',
}),
],
devtool: 'inline-source-map',
});
由于 MockComponent 内部可以有更多的组件,我依靠 Webpack 将所有样式注入到shadow root。
我正在使用style-loader 注入样式,但效果不佳。
我做错了什么,或者这个解决方案有什么替代方案。
【问题讨论】:
标签: css reactjs webpack shadow-dom webpack-style-loader