【发布时间】: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