Skip to content

Commit

Permalink
feat: add plugin to remove rtl (#2673)
Browse files Browse the repository at this point in the history
  • Loading branch information
oasis-cloud authored Nov 1, 2024
1 parent 08bab87 commit 6764b61
Show file tree
Hide file tree
Showing 15 changed files with 1,507 additions and 25 deletions.
31 changes: 31 additions & 0 deletions packages/nutui-optimize-css/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
通过配置 postcss 对组件库的 css 进行优化。

1. Taro 环境下的配置示例

```text
{
"mini": {
"postcss": {
"@nutui/optimize-css": {
"enable": true,
"config": {
"removeRtl": true,
"cssVariables": {
"include": [path.join(__dirname, 'variables.scss')],
"exclude": ["--nutui-color-primary-text"],
"type": "replace"
}
}
}
}
}
}
```

配置说明:

1. removeRtl:删除 rtl 相关样式
2. cssVariables
- include: 指定css变量的文件
- exclude: 设置哪些 css 变量不进行替换, 在 JS 控制 css 变量时可以使用 exclude 指定
- type: css 变量的替换方案,默认不处理,当设置 replace 时,可将 css 变量替换为实际值
18 changes: 18 additions & 0 deletions packages/nutui-optimize-css/build.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { defineBuildConfig } from 'unbuild'

export default defineBuildConfig({
failOnWarn: false,
entries: [
{
input: 'src/index',
outDir: 'dist',
format: 'cjs',
ext: 'cjs',
},
],
outDir: 'dist',
externals: ['postcss', 'postcss-css-variables', 'postcss-scss'],
rollup: {
emitCJS: true,
},
})
27 changes: 27 additions & 0 deletions packages/nutui-optimize-css/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
"name": "@nutui/optimize-css",
"version": "1.0.0",
"description": "remove rtl",
"main": "dist/index.cjs",
"scripts": {
"build": "unbuild",
"test": "pnpm build && vitest"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"@types/lodash": "^4.17.1",
"@types/node": "^20.14.11",
"@types/postcss-css-variables": "^0.18.3",
"ts-node": "^10.9.2",
"unbuild": "^2.0.0",
"vitest": "^1.5.0"
},
"dependencies": {
"lodash": "^4.17.21",
"postcss": "^8.4.39",
"postcss-css-variables": "^0.19.0",
"postcss-scss": "^4.0.9"
}
}
3 changes: 3 additions & 0 deletions packages/nutui-optimize-css/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { optimizeCss } from './postcss-plugins'

export default optimizeCss
102 changes: 102 additions & 0 deletions packages/nutui-optimize-css/src/postcss-plugins/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
import postcss, { ProcessOptions, Root, Document } from 'postcss'
import { merge } from 'lodash'
import cssVariables from 'postcss-css-variables'
import { parse } from 'postcss-scss'
import * as fs from 'fs'

export type CSSVariable = `--${string}`
export type FilePath = string

export interface Options {
removeRtl: boolean
cssVariables: {
include: FilePath[]
exclude: CSSVariable[]
type: 'normal' | 'replace'
}
}

function removeRtl(rule: any, canRemove: boolean) {
if (!canRemove) return

const sourceFile = rule.source.input.file
if (
sourceFile &&
sourceFile.indexOf('@nutui') === -1 &&
sourceFile.indexOf('@dongdesign') === -1
)
return
if (
rule.selector.indexOf('nut-rtl') > -1 ||
rule.selector.indexOf('[dir=rtl]') > -1
)
rule.remove()
}

async function replaceCssVariables(
root,
cssVariablesContent: string[],
exclude: string[] = []
) {
cssVariablesContent.push(root.toResult().css)
const options: ProcessOptions<Document | Root> = {
parser: parse,
from: undefined,
} as ProcessOptions<Root>
const replacedCss = postcss([
cssVariables({
preserve: (declaration) => {
if (exclude.includes(declaration.prop)) {
return true
}
const cssvars = declaration.value.match(/var\((--nutui-[\w\d-]+)\)/)
if (cssvars && exclude.includes(cssvars[1])) return true
return false
},
}),
]).process(cssVariablesContent.join('\n'), options).css

const replacedRoot = postcss.parse(replacedCss)
root.raws = replacedRoot.raws
root.nodes = replacedRoot.nodes
}

export function optimizeCss(opts: Options) {
const defaultConfig = {
removeRtl: false,
cssVariables: {
include: [],
type: 'normal',
},
}
const config = merge(defaultConfig, opts)
const cssVariablesContent: string[] = []
if (config.cssVariables.type !== 'normal') {
config.cssVariables.include.forEach((p: string) => {
let content = ''
try {
// 从绝对路径读取 CSS 变量的内容
content = fs.readFileSync(p).toString()
} catch (e) {
content = ''
}
cssVariablesContent.push(content)
})
}

return {
postcssPlugin: 'postcss-optimize-css',
OnceExit(root) {
if (config.cssVariables.type === 'replace') {
replaceCssVariables(
root,
cssVariablesContent,
config.cssVariables.exclude
)
}
},
Rule(rule) {
removeRtl(rule, opts.removeRtl)
},
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html

exports[`@nutui/optimize-css > remove rtl 1`] = `
"
"
`;
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html

exports[`@nutui/optimize-css > optimize css 1`] = `
":root {
--nutui-color-primary-text: blue;
}
.nut-address-footer-btn {
background: linear-gradient(135deg, yellow 0%, #fa2c19 100%);
color: blue;
color: var(--nutui-color-primary-text)
}
"
`;
26 changes: 26 additions & 0 deletions packages/nutui-optimize-css/test/remove-rtl.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import postcss from 'postcss'
import { describe, expect, it } from 'vitest'
import optimizeCss from '../dist/index.cjs'

const css = `
[dir=rtl] .ca, .xcdd {
margin-left: 0;
margin-right: 9px
}
[dir=rtl] .nut-address-exist-item-info, .nut-rtl .nut-address-exist-item-info {
margin-left: 0;
margin-right: 9px
}
`
describe('@nutui/optimize-css', () => {
it('remove rtl', async () => {
const a = await postcss([
optimizeCss({
removeRtl: true,
}),
]).process(css, { from: undefined })
const optimizedCsss = a.css.toString()
// @ts-ignore
expect(optimizedCsss).toMatchSnapshot()
})
})
28 changes: 28 additions & 0 deletions packages/nutui-optimize-css/test/replace-css-var.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import postcss from 'postcss'
import path from 'path'
import { describe, expect, it } from 'vitest'
import optimizeCss from '../dist/index.cjs'

const css = `
.nut-address-footer-btn {
background: linear-gradient(135deg, var(--nutui-color-primary-stop-1, #f53d6d) 0%, var(--nutui-color-primary-stop-2, #fa2c19) 100%);
color: var(--nutui-color-primary-text)
}
`
describe('@nutui/optimize-css', () => {
it('optimize css', async () => {
const a = await postcss([
optimizeCss({
cssVariables: {
include: [path.join(__dirname, 'variables.scss')],
exclude: ['--nutui-color-primary-text'],
type: 'replace',
},
}),
]).process(css, { from: undefined })
const optimizedCsss = a.css.toString()
console.log(optimizedCsss)
// @ts-ignore
expect(optimizedCsss).toMatchSnapshot()
})
})
4 changes: 4 additions & 0 deletions packages/nutui-optimize-css/test/variables.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
:root {
--nutui-color-primary-stop-1: red;
--nutui-color-primary-text: green;
}
4 changes: 4 additions & 0 deletions packages/nutui-optimize-css/test/variables.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
:root {
--nutui-color-primary-text: blue;
--nutui-color-primary-stop-1: yellow;
}
27 changes: 27 additions & 0 deletions packages/nutui-optimize-css/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"allowSyntheticDefaultImports": true,
"experimentalDecorators": true,
"moduleResolution": "node",
"noImplicitAny": false,
"noUnusedLocals": true,
"noUnusedParameters": true,
"removeComments": false,
"resolveJsonModule": true,
"skipLibCheck": true,
"strictNullChecks": true,
"target": "ES2015",
"outDir": "./dist",
"rootDir": "./src",
"module": "ESNext",
"sourceMap": true,
"declaration": true,
"declarationDir": "types",
"isolatedModules": false,
"types": ["node"]
},
"include": [
"./src"
]
}
7 changes: 7 additions & 0 deletions packages/nutui-optimize-css/vitest.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { defineConfig } from 'vitest/config'

export default defineConfig({
test: {
// ... Specify options here.
},
})
18 changes: 12 additions & 6 deletions packages/nutui-taro-demo/config/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,15 @@ const config = {
alias: {
'@nutui/nutui-react-taro/dist/locales/en-US.ts': path.resolve(
__dirname,
'../../../src/locales/en-US.ts'
'../../../src/locales/en-US.ts',
),
'@/packages': path.resolve(__dirname, '../../../src/packages'),
'@/sites': path.resolve(__dirname, '../../../src/sites'),
'@/locales': path.resolve(__dirname, '../../../src/locales'),
'@/utils': path.resolve(__dirname, '../../../src/utils'),
'@nutui/nutui-react-taro': path.resolve(
__dirname,
'../../../src/packages/nutui.react.taro.ts'
'../../../src/packages/nutui.react.taro.ts',
),
},
sass: {
Expand Down Expand Up @@ -75,6 +75,12 @@ const config = {
h5: {
publicPath: '/',
staticDirectory: 'static',
compile: {
include: [
path.resolve(__dirname, '..', 'node_modules/@tarojs/components'),
path.resolve(__dirname, '../../..', 'src'),
],
},
postcss: {
pxtransform: {
enable: true,
Expand Down Expand Up @@ -106,14 +112,14 @@ const config = {
},
output: {
environment: {
asyncFunction: true
}
}
asyncFunction: true,
},
},
},
isWatch: true,
}

module.exports = function (merge) {
module.exports = function(merge) {
if (process.env.NODE_ENV === 'development') {
return merge({}, config, require('./dev'))
}
Expand Down
Loading

0 comments on commit 6764b61

Please sign in to comment.