本文将指导 Rollup 插件开发新手,逐步开发一个用于导入 JSON 文件的插件。从简单的 JSON 导入功能出发,逐步扩展到支持 JSON5 格式,并通过优化性能加入缓存机制。最后,将介绍插件中使用到的关键钩子及其作用,并展示如何在项目中配置和使用该插件。
一、实现基本的 JSON 导入功能
首先,我们开发一个简单的 Rollup 插件,使其能够处理 .json 文件的导入,将 JSON 内容转换为 ES 模块的默认导出。
1.1 编写插件代码
创建 plugins/rollup-plugin-json.mjs 文件,编写如下代码:
export default function jsonPlugin(options = {}) {
return {
name: 'json',
// 处理模块解析
resolveId(source, importer) {
if (source.endsWith('.json')) {
// 返回模块的绝对路径,指示 Rollup 由插件处理该模块
return source;
}
return null;
},
// 转换模块内容
transform(code, id) {
if (!id.endsWith('.json')) return null;
let parsed;
try {
parsed = JSON.parse(code);
} catch (err) {
this.error(`解析 JSON 文件 ${id} 时出错: ${err.message}`);
}
const jsonString = JSON.stringify(parsed);
const transformedCode = `export default ${jsonString};`;
return {
code: transformedCode,
map: { mappings: '' } // 无源映射
};
}
};
}
1.2 配置 Rollup 使用插件
在示例项目中,配置 Rollup 使用该插件。
示例数据 data.json
在 src/data.json 中添加示例数据:
{
"name": "rollup"
}
创建 main.js
在 src/main.js 中导入 JSON 文件:
import data from './data.json';
console.log(`Hello ${data.name}`);
创建 rollup.config.js
在项目根目录下创建 rollup.config.js,配置 Rollup 使用自定义插件:
import jsonPlugin from "./plugins/rollup-plugin-json.mjs";
export default {
input: "./src/main.js",
output: {
file: 'bundle.js',
format: 'esm',
},
plugins: [
jsonPlugin()
],
};
1.3 运行 Rollup 构建
执行 Rollup 构建命令:
npx rollup -c
构建后生成的 bundle.js 内容如下:
var data = {"name":"rollup"};
console.log(`Hello ${data.name}`);
二、扩展支持 JSON5 格式
JSON5 是 JSON 的一个超集,允许更灵活的语法,如单引号、注释等。我们通过集成 json5 库,使插件支持 JSON5 格式。
2.1 安装 JSON5 库
在项目根目录下安装 json5:
pnpm add json5
2.2 修改插件代码
修改 plugins/rollup-plugin-json.mjs,添加对 JSON5 的支持:
import JSON5 from 'json5';
export default function jsonPlugin(options = {}) {
const { allowJSON5 = false } = options;
return {
name: 'json',
resolveId(source, importer) {
if (source.endsWith('.json')) {
return source;
}
return null;
},
transform(code, id) {
if (!id.endsWith('.json')) return null;
let parsed;
try {
parsed = allowJSON5 ? JSON5.parse(code) : JSON.parse(code);
} catch (err) {
this.error(`解析 JSON 文件 ${id} 时出错: ${err.message}`);
}
const jsonString = JSON.stringify(parsed);
const transformedCode = `export default ${jsonString};`;
return {
code: transformedCode,
map: { mappings: '' }
};
}
};
}
2.3 配置插件使用 JSON5
在 rollup.config.js 中启用 JSON5 支持:
import jsonPlugin from "./plugins/rollup-plugin-json.mjs";
export default {
input: "./src/main.js",
output: {
file: 'bundle.js',
format: 'esm',
},
plugins: [
jsonPlugin({
allowJSON5: true
})
],
};
三、优化插件:添加缓存机制
在大型项目中,频繁读取和解析 JSON 文件可能影响构建性能。通过添加缓存机制,可以避免重复处理相同的文件,提升构建效率。
3.1 修改插件代码
修改 plugins/rollup-plugin-json.mjs,引入缓存逻辑:
import JSON5 from 'json5';
import jsonminify from 'jsonminify'; // 若需要压缩
export default function jsonPlugin(options = {}) {
const {
allowJSON5 = false,
minify = false,
} = options;
const cache = new Map();
return {
name: 'json',
resolveId(source, importer) {
if (source.endsWith('.json')) {
return source;
}
return null;
},
transform(code, id) {
if (!id.endsWith('.json')) return null;
// 缓存检查
if (cache.has(id)) {
return cache.get(id);
}
let parsed;
try {
parsed = allowJSON5 ? JSON5.parse(code) : JSON.parse(code);
} catch (err) {
this.error(`解析 JSON 文件 ${id} 时出错: ${err.message}`);
}
let jsonString = JSON.stringify(parsed);
if (minify) {
jsonString = jsonminify(jsonString);
}
const transformedCode = `export default ${jsonString};`;
const result = {
code: transformedCode,
map: { mappings: '' }
};
// 存入缓存
cache.set(id, result);
return result;
}
};
}
3.2 配置压缩选项
在 rollup.config.js 中启用压缩:
import jsonPlugin from "./plugins/rollup-plugin-json.mjs";
export default {
input: "./src/main.js",
output: {
file: 'bundle.js',
format: 'esm',
},
plugins: [
jsonPlugin({
allowJSON5: true,
minify: true
})
],
};
重新构建项目,插件将压缩 JSON 数据,减小输出文件大小。
四、插件中使用到的关键钩子解析
在开发过程中,我们主要使用了以下 Rollup 钩子:
4.1 resolveId 钩子
作用:决定模块的解析方式,返回模块的路径或 ID。
使用场景:当插件需要处理特定类型的模块(如 .json 文件)时,使用 resolveId 钩子拦截模块解析过程,指示 Rollup 由插件处理该模块。
示例解析:
resolveId(source, importer) {
if (source.endsWith('.json')) {
return source; // 告诉 Rollup 由插件处理该模块
}
return null; // 让 Rollup 继续其他解析逻辑
}
4.2 transform 钩子
作用:转换模块内容,返回转换后的代码和源映射。
使用场景:对模块内容进行处理,如编译、转换、优化等。在我们的插件中,用于将 JSON 内容转换为 ES 模块的默认导出。
五、总结与使用
通过本文的介绍,你已经学会了如何基于 Rollup 开发一个用于导入 JSON 文件的插件。从最基础的 JSON 导入功能出发,逐步扩展到支持 JSON5 格式,并通过添加缓存机制优化插件性能。关键钩子的解析帮助你理解插件在 Rollup 构建过程中的作用。
使用步骤回顾
- 编写插件代码:在代码中实现
resolveId和transform钩子,处理 JSON 文件的导入与转换。 - 扩展功能:集成
json5支持,允许解析更灵活的 JSON5 格式。 - 优化性能:添加缓存机制,避免重复处理相同的 JSON 文件。
- 配置 Rollup:在
rollup.config.js中引入并配置自定义插件,根据需求启用 JSON5 支持和压缩选项。 - 验证效果:通过构建示例项目,确保插件正确导入并转换 JSON 文件内容。
掌握了这些基础后,你可以根据项目需求,进一步扩展插件功能,如支持更多文件类型、增加更多配置选项等。Rollup 的插件系统极具灵活性,鼓励开发者根据实际需求进行定制化开发。
希望本文对你开发 Rollup 插件有所帮助,祝你在前端开发的道路上不断进步!