前言
在项目开发中,读取转换成base64的图片,base64内容过长,需要使用单独文件进行保存。
本文介绍使用webpack和vite如何读取文件原始内容。
1. 实际操作
- 创建webpack/vite的项目,创建img.data文件用于存储base64位数据
- 直接通过import引入文件,项目报错
如图所示:
原因是因为webpack之所以能够读取.vue
等其他后缀名称的文件,是有专门的loader进行处理转换,当遇到后缀为.data
的没有对应的loader进行处理。
主要解决方案看项目使用什么进行打包编译,介绍webpack和vite的处理方式:
1.1 webpack项目
如果是webpack项目:
- 需要安装
npm i raw-loader -D
- 配置webpack的loader处理机制
例如: vue.config.js
module.exports = {
configureWebpack: {
module: {
rules: [
{
test: /\.data$/,
use: ['raw-loader']
}
]
},
},
};
再次运行,正常读取。
raw-loader源码:
import { getOptions } from 'loader-utils';
import { validate } from 'schema-utils';
import schema from './options.json';
export default function rawLoader(source) {
const options = getOptions(this);
validate(schema, options, {
name: 'Raw Loader',
baseDataPath: 'options',
});
const json = JSON.stringify(source)
.replace(/\u2028/g, '\u2028')
.replace(/\u2029/g, '\u2029');
const esModule =
typeof options.esModule !== 'undefined' ? options.esModule : true;
return `${esModule ? 'export default' : 'module.exports ='} ${json};`;
}
工作原理:
loader-utils
和schema-utils
的函数,用于处理 loader 的选项以及验证选项的合法性。- 使用
JSON.stringify(source)
将输入的源代码转换成 JSON 格式的字符串。替换字符串中的特殊字符换行和分隔符进行了转义,避免语法错误。 - 确定导出模块的类型,将转换后的 JSON 字符串作为模块的内容导出。
总体来说,工作原理是接收源代码并根据选项将其转换为字符串,然后根据选项导出为 ES 模块或 CommonJS 模块。
1.2 vite项目
如果是vite项目,就不需要下载raw-loader
,vite项目内置处理读取源文件内容的方式。
写法如下:
<img :src="base" alt="">
import base from './img.data?raw';
在 Vite 的上下文中,?raw
查询参数可能意味着你希望以原始(raw)的方式导入这个模块,即不对其进行任何特殊的转换或打包,而是直接将其作为字符串引入。
可以看下vite-plugin-raw源码:
const fs = require('fs');
interface Props{
/**
* Regex to match file, like /\.svg$/
*/
match: RegExp | RegExp[];
/**
* exclude file
*/
exclude?: RegExp | RegExp[];
}
interface ReturnValue{
code?: string;
}
export default function ({match, exclude}: Props) {
return {
name: 'vite-plugin-raw',
async transform (_: string, id: string): Promise<ReturnValue> {
const files = Array.isArray(match) ? match : [match];
const excludes = exclude ? (Array.isArray(exclude) ? exclude : [exclude]) : exclude;
const excludeBool = excludes ? !(excludes.find((v) => v.test(id))) : !excludes;
const isRaw = id.endsWith("?raw");
if ((files.find((v) => v.test(id)) && excludeBool) || isRaw) {
if (isRaw) {
id = id.replace("?raw", "");
}
const buf = fs.readFileSync(id);
return {
code: `export default \`${buf}\``
};
} else {
return {};
}
}
}
}
工作原理:
-
使用
fs
模块,用于读取文件内容 -
transform
方法是 Vite 构建过程中用于对文件进行转换的一个异步函数。它接收两个参数:_
(不使用)和id
(文件路径),并返回一个 Promise,该 Promise 的解析值是一个对象,其中包含了转换后的代码。 -
处理文件
- 在
transform
方法中,首先将match
字段转换为数组,并检查是否存在exclude
字段。如果存在,也将其转换为数组。然后根据id
是否以?raw
结尾来判断是否需要以原始方式处理文件。 - 如果文件匹配了指定的规则,并且没有被排除,或者文件名以
?raw
结尾,则读取文件的内容,并将其作为字符串模板导出。如果不符合条件,则返回一个空对象。
- 在
总结一下:在构建过程中根据指定的规则如?raw
规则读取文件内容,并将其作为字符串导出。
2. 总结
本文介绍了在项目开发中,读取转换成 base64 的图片时,由于 base64 内容过长,需要使用单独文件进行保存的情况。分别讨论了在 webpack 项目和 Vite 项目中如何读取文件的原始内容,也简单对文件处理的源码进行简单解析。
在 webpack 项目中,通过使用 raw-loader
,可以直接在 webpack 配置中添加对 .data
后缀文件的处理规则,从而实现对文件内容的读取和导出。
而在 Vite 项目中,不需要额外安装 raw-loader
,Vite 内置了处理读取源文件内容的方式,通过在导入路径中添加 ?raw
查询参数,可以实现对文件内容的原始导入。
如有错误,请指正O^O!
原文链接:https://juejin.cn/post/7351728888982503460 作者:一诺滚雪球