如何将 CSS 文件内容导入 Javascript 变量

con*_*exo 5 css shadow-dom webpack custom-element es6-modules

考虑一个使用 shadow DOM 的非常简单的自定义元素:

customElements.define('shadow-element', class ShadowElement extends HTMLElement {
  constructor() {
    super();
    this.styleTag = document.createElement('style');
    this.styleTag.textContent= `
.root::before { 
  content: "root here!"; 
  color: green; 
}
    `
    this.shadow = this.attachShadow({mode: 'closed'});
    this.root = null;
  }
  
  connectedCallback() {
    this.root = document.createElement('div');
    this.root.className = 'root';
    this.shadow.append(this.root, this.styleTag);
  }
})
Run Code Online (Sandbox Code Playgroud)
<shadow-element></shadow-element>
Run Code Online (Sandbox Code Playgroud)

为了将 CSS 放入 shadow DOM,我创建了一个style标签,并将其附加到 shadow root 中。到目前为止,这一切都很好。

现在对于更复杂的 CSS,我想shadow-element.css在与 .css 文件位于同一文件夹中的文件中编写它shadow-element.js。除了关注点的分离, 我还需要 IDE 语法突出显示和 CSS 创作的完成,所以我真的希望将 CSS 放在一个单独的专用文件中。

我想将该 CSS 文件的内容导入到 Javascript 变量中,例如

import styles from './shadow-element.css'; // obviously doesn't work
Run Code Online (Sandbox Code Playgroud)

在使用它的项目中,我们有一个工作webpack堆栈,允许导入 CSS(甚至 SCSS),但不幸的是,导入的 CSS 成为了bundle.css其中的一部分——这显然一点用处都没有,因为该元素使用了 shadow DOM。

有没有人有解决方案?我也对替代解决方案持开放态度,只要它不需要我在 .js 文件中创作我的 CSS。

编辑:我知道@import './shadow-elements.css';style标签内使用的选项,但我更喜欢将导入的 CSS 捆绑到我的 Javascript 包中的解决方案(作为组件代码的一部分)。

小智 8

当您使用webpack 时,您可以使用raw-loader将文本文件(在您的情况下为 CSS)导入字符串:

npm install raw-loader --save-dev
Run Code Online (Sandbox Code Playgroud)

您可以在每个文件中内联使用它:

import css from 'raw-loader!./shadow-element.css';

customElements.define('shadow-element', class ShadowElement extends HTMLElement {
  constructor() {
    super();
    this.styleTag = document.createElement('style');
    this.styleTag.innerText = css;
    this.shadow = this.attachShadow({mode: 'closed'});
    this.root = null;
  }

  connectedCallback() {
    this.root = document.createElement('div');
    this.root.className = 'root';
    this.shadow.append(this.root, this.styleTag);
  }
})

Run Code Online (Sandbox Code Playgroud)