javascript - 具有 Preact SSR 和 RTL 支持的 Emotion.js
问题描述
我有一个 preact SSR 应用程序并使用 Emotion JS 10 进行样式设置。
我想为此添加 RTL 支持,因此使用createEmotion
并createEmotionServer
使用结果renderStylesToString
来呈现应用程序。
但是,在创建createEmotion
它时需要使用我添加插件的stylis-rtl
插件,但这总是会应用 RTL 样式,而我希望根据每个请求应用 RTL 样式。
我找不到任何方法来告诉情感应用并在每个请求的基础上获取 RTL 样式。他们确实对 React 16 有直接的实现,您可以将每个请求的多个缓存传递给CacheProvider
.
但我似乎无法为 Preact 解决这个问题。
一种解决方案可能是为 RTL 提供不同的 webpack 构建,但这将是不必要的开销。
编辑 1:对于希望实现类似功能的任何人,这是我的方法
客户端以及css
服务器上的导入:
import stylisRTL from 'stylis-rtl';
import createEmotion from 'create-emotion';
const {
cx: cxRTL,
injectGlobal: injectGlobalRTL,
css: cssRTL,
cache: cacheRTL,
keyframes: keyframesRTL
} = createEmotion({
key: 'c',
stylisPlugins: [stylisRTL]
});
const {
cx: cxLTR,
injectGlobal: injectGlobalLTR,
css: cssLTR,
cache: cacheLTR,
keyframes: keyframesLTR
} = createEmotion({
key: 'c',
stylisPlugins: []
});
const runForBoth = (rtlFn, ltrFn) => (...args) => {
//this would be ur store sent in html to check whether it is in rtl or ltr mode
const isRTL = typeof window !== 'undefined' && window.__PRELOADED_STATE__.shell.RTL;
let result;
if (__BROWSER__) {
if (isRTL) {
result = rtlFn(...args);
} else {
result = ltrFn(...args);
}
} else {
result = ltrFn(...args);
rtlFn(...args);
}
return result;
};
export const cx = runForBoth(cxRTL, cxLTR);
export const injectGlobal = runForBoth(injectGlobalRTL, injectGlobalLTR);
export const css = runForBoth(cssRTL, cssLTR);
export const keyframes = runForBoth(keyframesRTL, keyframesLTR);
export const cacheEmotionLTR = cacheLTR;
export const cacheEmotionRTL = cacheRTL;
对于 SSR:
const { renderStylesToString: renderStylesToStringLTR } = createEmotionServer(cacheEmotionLTR);
const { renderStylesToString: renderStylesToStringRTL } = createEmotionServer(cacheEmotionRTL);
我创建 2 个缓存并根据请求标头决定renderStylesToString
使用哪个缓存
我担心的一个问题runForBoth
是技术上的错误。但它现在正在工作。
我不想改变css
Fn 的导入方式,因为现在我可以使用这个自定义情感导入并在 webpack 中为其命名
解决方案
如果您想根据请求进行此操作,那么您应该创建 2 个情感实例(一个带有插件,一个没有插件)。此外,您必须为每个请求使用正确的实例 - 最简单的方法可能是使用上下文:将情感放在上下文中并从那里使用它而不是从 import 语句。
推荐阅读
- android - RecyclerView - 在 notifyItemInserted(0) 后保持在 0 位置
- mariadb - 过滤 MariaDB 中 SELECT 时显示的条目
- unit-testing - java.lang.NoSuchMethodError: com.google.common.base.CharMatcher.whitespace()
- azure-cli - 如何配置警报以应用于所有实例(选择 *)
- r - 适用于 Windows 的 R 版本和 ncdf 兼容性
- xamarin.forms - AWS S3 文件传输 Xamarin 表单的好示例?
- html - 如何删除 Ion-Toolbar 上的边框?
- sql-server - 拆分分隔字符串并将它们插入表列 SQL 2014
- ruby - 红宝石!方法或过程
- android - 使用 Dagger 2 将属性注入 ViewModel