PostCSS
GitHub - postcss/postcss: Transforming styles with JS plugins
插件
autoprefixer
cssnano
postcss-url
处理CSS文件中的 url()
,如引入字体、图片等资源
核心参数
url :支持 “rebase” |
“copy” | “inline” 3种模式 |
参数组合
rebase
仅转换 url()
路径
- assetsPath - 复制资产的目录(相对于或绝对值)
inline
处理为DataURL
- basePath - 搜索资产的路径或路径数组(相对于或绝对路径)
- encodeType - base64、encodeURI、encodeURIComponent
- includeUriFragment - 在 URI 末尾包含片段标识符
- maxSize - 以千字节为单位的文件大小
- fallback - 复制、重存或自定义文件大小大于 maxSize 时的函数
- ignoreFragmentWarning - 当 SVG URL 内嵌片段时不发出警告
- optimizeSvgEncode - 减少内联 SVG 的大小(IE9 以上,Android 3 以上)
copy
- basePath - 搜索资产的路径或路径数组(相对于或绝对路径)
- assetsPath - 复制资产的目录(相对于或绝对路径)
- useHash - 使用文件哈希(xxhash)命名
- hashOptions-散列函数的选项
自定义处理 {Function}
- multi - 与其他选项一起处理
实践
自定义url参数处理:
支持 @
标识符作为根路径解析;
同时支持 url()
根路径、相对路径解析
支持 maxSize
,useHash
options
const crypto = require("crypto");
const mime = require("mime-types");
plugins: [
postcssUrl({
assetsPath: "img", // 图片放置目录
maxSize: 10, // 小于10kb的图片转为base64
useHash: true, // 文件名添加哈希值
url: (asset, dir, { assetsPath, maxSize, useHash }) => {
const { pathname, hash, search } = asset;
// 源文件路径
const isAbsolute = pathname.startsWith("@");
const sourcePath = isAbsolute
? path.join(__dirname, pathname.replace("@", ""))
: path.join(dir.from, pathname);
const fileData = fs.readFileSync(sourcePath);
// 输出文件路径
let assetName = path.basename(pathname);
if (useHash) {
const hash = crypto
.createHash("sha256")
.update(fileData)
.digest("hex")
.slice(0, 8);
const ext = path.extname(assetName);
const name = path.basename(assetName, ext);
assetName = assetName.replace(
`${name}${ext}`,
`${name}.${hash}${ext}`
);
}
const targetPath = path.join(dir.to, assetsPath, assetName);
// maxSize
const stats = fs.statSync(sourcePath);
const fileSizeInBytes = stats.size;
const fileSizeInKilobytes = fileSizeInBytes / 1024;
if (maxSize && fileSizeInKilobytes < maxSize) {
const mimetype = mime.lookup(assetName);
const data = fileData.toString("base64");
return `data:${mimetype};base64,${data}`;
}
// copy文件
const dirToCheck = path.dirname(targetPath);
if (!fs.existsSync(dirToCheck)) {
fs.mkdirSync(dirToCheck, { recursive: true });
}
fs.copyFileSync(sourcePath, targetPath);
// 转换 url
let transformUrl = path.relative(dir.to, targetPath);
if (hash) transformUrl += hash;
if (search) transformUrl += search;
transformUrl = transformUrl.replace(/\\/g, "/");
return transformUrl;
},
}),
],
background-image: url("@/src/images/sprite/emoji_sprite.png")
background-image: url("../images/sprite/emoji_sprite.png")