【问题标题】:other ways to use style-loader without bundling style-loader lib into every bundled style?其他使用样式加载器的方法,而不将样式加载器库捆绑到每个捆绑的样式中?
【发布时间】:2022-01-14 18:39:23
【问题描述】:

我使用 webpack 5 来捆绑我的 css 样式,我想按原样包含每个模块。没有将其构建到单个文件中,但我注意到当我使用 style-loader 时,小于 1kb 甚至 5kb 到 10kb 的样式都在 30kb 以上。

我假设这是因为样式加载器代码将 css 注入正文。我尝试使用迷你 css 提取,但添加 css 作为链接标签不适用于 SPFX。所以我最终将它与文件加载器捆绑在一起,因此它是一个字符串并使用自定义脚本来注入样式。

export const attrReducer = (acc, cv) => cv[1] !== null || typeof cv[1] !== 'undefined'
  ? acc.concat(`${cv[0]}="${cv[1]}" `)
  : acc

export const mapToAttr = (o) => Object.entries(o).reduce(attrReducer, ``)

export const makeStyleTagLinkString = (props) => `<link ${mapToAttr(props)}></link>`
export const makeStyleTagString = ({ content, ...props }) => `<style ${mapToAttr(props)}>${content}</style>`

export const injectStyleTag = (props) => (url) => (
  !document.querySelector(`style[data-href="${url}"]`)
    ? document.head.insertAdjacentHTML('beforeend', makeStyleTagString({ props, href: url }))
    : null
);
export const injectStyleLinkTag = (props) => (url) => (content) => (
  !document.querySelector(`style[data-href="${url}"]`)
    ? document.head.insertAdjacentHTML('beforeend', makeStyleTagLinkString({ ...props, content: content }))
    : null
);

上面的设置很适合我的设置,但这真的不是我最终想要使用的,因为 webpack 应该为我处理。

另一个问题是 style-loader 对我来说做得很好,除了增加每个 css 模块大小的问题之外,是在构建时根据样式的内容来操作样式标签,这对我很有用因为我可以根据 css 的内容应用容器查询 polyfill(或任何其他)。例如:

{
  loader: "style-loader",
  options: {
    styleTagTransform: function (css, style) {
      css.indexOf('@container') > -1
        ? style.setAttribute('cqfill', '')
        : null;
      style.innerHTML = css;
      document.head.appendChild(style);
    },
  },
},

SPFX 确实有自己的加载样式的实现,我尝试过,但它不能很好地与 container-query-polyfill 一起使用。也没有任何选项可以向样式标签添加任何内容或以任何方式对其进行操作。

export default class JQueryAccordionWebPart extends BaseClientSideWebPart<IJQueryAccordionWebPartProps> {
  protected onInit(): Promise<void> {
    SPComponentLoader.loadCss('https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.min.css');
    return super.onInit();
  }

  // ...
}

所以问题是是否有其他方法可以将 css 文件导出为资产并使用任一样式加载器作为单独的库来构建样式或链接标签? 或者我可以包含的任何其他库都可以做到这一点,而无需使用自定义代码。

【问题讨论】:

    标签: javascript css webpack webpack-style-loader


    【解决方案1】:

    不确定我是否理解问题的所有部分。对于style-loadermini-css-extract-plugin,重要的是要知道在开发模式下,样式将始终从 JS 文件中注入,因为这样更快。只有在生产版本中,样式才会出现在单独的 CSS 文件中 (process.env.NODE_ENV === 'production')。

    【讨论】:

    • 这并没有真正奏效。据我所知,我没有找到任何支持你所说的信息。对于我所做的测试,即使我将其设置为生产,样式加载器代码也会针对每个发出的文件进入 js 包,而且仅将“injectType”更改为“linkTag”,除了将样式内容放入href 属性,我知道这很奇怪,但这就是发生的事情。所以要么我遗漏了一些东西,要么如果你知道你可以给我指出这个工作的一个例子。
    • @RicardoSilva 你是对的,我记错了。实际上,mini-css-extract-plugin 和 style-loader 之间的切换必须手动完成。这是如何做到这一点的documentation with an example。现在也需要在我的设置中更正此问题;)
    • mini-css-extract-plugin 不适用于我的 spfx 设置之一,polyfill 无法使用它。这显然不是 mini-css-extract-plugin 的问题,但我正在尝试寻找其他方法与 style-loader 捆绑,完全符合我的需求,唯一的问题是即使 css 文件是它具有的 js 模块只是一个导出的字符串,而不是一个包含 30kb 样式加载器的完整模块。我已经这样做了,但是我不想为此使用自定义代码。
    猜你喜欢
    • 2018-07-16
    • 2018-11-09
    • 2016-09-05
    • 2018-08-13
    • 2019-01-30
    • 2012-09-24
    • 1970-01-01
    • 1970-01-01
    • 2014-11-29
    相关资源
    最近更新 更多