Вот простое решение, которое требует извлечения и добавления облегченного webpack-rtl-plugin
.
После запуска
npx create-react-app react-rtl
cd react-rtl
yarn eject
yarn add -D webpack-rtl-plugin @babel/plugin-transform-react-jsx-source
Перейти кconfig/webpack.config.js
и внесите некоторые изменения:
// import the plugin
const WebpackRTLPlugin = require('webpack-rtl-plugin')
// ...
module: { ... }
plugins: [
// ...,
// use the plugin
new WebpackRTLPlugin({ diffOnly: true })
].filter(Boolean),
// ...
На этом этапе, если вы запустите yarn build
и посмотрите папку build/static/css
, вы должны увидеть дополнительный файл .rtl.css
который содержит ваши стили RTL.Затем нам нужно указать webpack
использовать MiniCssExtractPlugin.loader
для разработки, чтобы он служил стилям через теги link
вместо встроенных стилей:
// common function to get style loaders
const getStyleLoaders = (cssOptions, preProcessor) => {
const loaders = [
isEnvDevelopment && { loader: MiniCssExtractPlugin.loader }, // <-- use this
// isEnvDevelopment && require.resolve('style-loader'), <-- instead of this
и не забывал плагин, lol:
module: { ... }
plugins: [
// ...,
// isEnvProduction && <-- comment this out
new MiniCssExtractPlugin({
// Options similar to the same options in webpackOptions.output
// both options are optional
filename: 'static/css/[name].[contenthash:8].css',
chunkFilename: 'static/css/[name].[contenthash:8].chunk.css',
}),
// ...
].filter(Boolean),
И отсюда вы можете наконец получить свою таблицу стилей по умолчанию href
и использовать для вставки стилей RTL.Вот как вы можете это реализовать:
class RtlCssBundleService {
constructor() {
this.rtlApplied = false
this.rtlStyles = [];
this.ltrStyles = Array.from(
document.querySelectorAll('link[rel="stylesheet"]')
)
}
insert = () => {
if (this.rtlApplied) { return }
this.rtlApplied = true
if (this.rtlStyles.length) {
return this.rtlStyles.forEach(style => {
document.body.appendChild(style)
})
}
this.rtlStyles = this.ltrStyles.map(styleSheet => {
const link = document.createElement("link")
link.href = styleSheet.href.replace(/\.css$/, '.rtl.css')
link.rel = "stylesheet"
document.body.appendChild(link)
return link
})
}
detach = () => {
this.rtlApplied = false
this.rtlStyles.forEach(style => {
document.body.removeChild(style)
})
}
toggle = () => {
return this.rtlApplied
? this.detach()
: this.insert()
}
}
const rtlStyles = new RtlCssBundleService()
export default rtlStyles
Затем используйте это из любого из ваших компонентов.Так или иначе, я уверен, что я что-то пропустил и, возможно, это ужасный подход, но, похоже, он работает, и вот демо 1034 *