【问题标题】:Emotion.js with Preact SSR and RTL support具有 Preact SSR 和 RTL 支持的 Emotion.js
【发布时间】:2019-05-31 12:13:29
【问题描述】:

我有一个 preact SSR 应用程序并使用 Emotion JS 10 进行样式设置。

我想为此添加 RTL 支持,因此使用了 createEmotioncreateEmotionServer 并使用生成的 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 中为其设置别名

【问题讨论】:

    标签: javascript webpack preact emotion


    【解决方案1】:

    如果您想根据请求进行此操作,那么您应该创建 2 个情感实例(一个带有插件,一个不带插件)。此外,您必须为每个请求使用正确的实例 - 最简单的方法可能是使用上下文:将情感放在上下文中并从那里使用它而不是从 import 语句。

    【讨论】:

    • 我已经实现了类似的东西,但不确定这是否是正确的方法?在答案编辑中添加了实现
    • 如果它可以工作,那么它就可以工作,ofc 这个解决方案稍微不太理想,因为你将所有东西都运行了两次 - 但如果有适当的缓存,它应该没什么大不了的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多