@saco/rem-plugin
v1.0.1
Published
Vite / Webpack rem adaptation plugin: postcss-pxtorem + root font-size injection
Maintainers
Readme
@saco/rem-plugin
px → rem(postcss-pxtorem)+ 根字号适配。两个入口:
| 导出 | 用途 |
|------|------|
| @saco/rem-plugin | 运行时:当前根字号、视口宽度、配置 |
| @saco/rem-plugin/plugin | Vite / Webpack 插件 |
安装
Vite:
pnpm add -D @saco/rem-plugin业务代码若 import 运行时 API,请把本包放进 dependencies(不要只装 -D)。
Webpack(需额外安装 peer 依赖):
pnpm add @saco/rem-plugin
pnpm add -D postcss-loader html-webpack-pluginpostcss-loader:注入postcss-pxtorem(px → rem)html-webpack-plugin:向 HTML 注入 runtime<script src>
配置项
vitePlugin(options) / webpackPlugin(options) 共用:
| 字段 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| output | string | static/js | runtime 输出目录(须在 outDir 内,可写 dist/static/js) |
| designWidth | number | 1920 | 设计稿宽度 |
| rootValue | number | 16 | 设计稿下 1rem 对应的 px |
| minRoot | number | 12 | 根字号下限 |
| maxRoot | number | 16 | 根字号上限 |
| minPixelValue | number | 2 | 小于该值的 px 不转 rem |
| selectorBlackList | (string \| RegExp)[] | ['.norem'] | 不转换的选择器 |
开发时继续写 px。不想转换时可用 1Px / PX,或加类名 .norem。
Vite
import { defineConfig } from 'vite'
import { vitePlugin } from '@saco/rem-plugin/plugin'
export default defineConfig({
plugins: [
vitePlugin({
output: 'dist/static/js',
designWidth: 1920,
rootValue: 16,
minRoot: 12,
maxRoot: 16,
}),
],
})Webpack
确保工程已配置 postcss-loader,并使用 html-webpack-plugin 生成 HTML。
const { webpackPlugin } = require('@saco/rem-plugin/plugin')
module.exports = {
plugins: [
webpackPlugin({
output: 'dist/static/js',
designWidth: 1920,
rootValue: 16,
}),
],
}运行时
根字号仍随窗口 实时 变化(head 注入的 runtime 听 resize)。业务侧不要解构,直接读 rem.size:
import { rem, watchRem, setRemUserRoot, getRemUserRoot } from '@saco/rem-plugin'
rem.size // 当前 html 根字号(px),每次访问都是最新值
rem.width // 当前视口宽度
rem.scale // width / designWidth
rem.userRoot // 设计稿宽度下的偏好根字号(默认 = rootValue)
rem.config // { designWidth, rootValue, minRoot, maxRoot }
// ❌ const { size } = rem 会变成死快照
// 设置页「标准 / 较大 / 最大」改偏好根字号,不要写 --font-size:
setRemUserRoot(18)
getRemUserRoot()
// 需要驱动 Vue / 视图更新时订阅:
const stop = watchRem(({ size, width, scale, userRoot, config }) => {
// 立刻回调一次,之后每次 resize / setRemUserRoot 再回调
})setRemUserRoot(px) 改的是设计稿宽度下的 1rem。公式:
size = clamp(minRoot * factor, maxRoot * factor, (width / designWidth) * userRoot)
factor = userRoot / rootValue。不按比例抬 maxRoot 的话,userRoot = 18 会被默认 maxRoot: 16 钳成 16。
偏好会写入 localStorage 键 __SACO_REM_USER_ROOT__,head 注入的 runtime 启动时先读,刷新不会先闪默认 16。
Vue 示例:
import { rem, watchRem } from '@saco/rem-plugin'
import { ref, onMounted, onUnmounted } from 'vue'
const size = ref(rem.size ?? 0)
onMounted(() => {
const stop = watchRem((s) => {
size.value = s.size
})
onUnmounted(stop)
})未接入插件、或 runtime 尚未执行时,rem.size 等为 undefined。
工作方式
- 构建配置:
vitePlugin/webpackPlugin(@saco/rem-plugin/plugin) - 启动 / 构建时:生成 head 注入的 runtime JS,并写入
__SACO_REM_CONFIG__ - 业务:
import { rem, watchRem } from '@saco/rem-plugin'读实时大小和配置
- 缓存:
node_modules/.cache/@saco/rem-plugin/saco-rem-runtime.js - 产物:由
output指定,默认static/js/saco-rem-runtime.js(相对 outDir)
