npm install -g pnpm(非必须)
# 1. 创建项目并初始化
mkdir rollup-demo && cd rollup-demo
npm init -y
# 2. 安装 Rollup(开发依赖)
npm install rollup --save-dev
# 3. 执行打包命令
# 方式1:直接执行 rollup(使用默认配置文件)
npx rollup -c
# 方式2:在 package.json 中配置脚本(更常用)
# 编辑 package.json,添加:
# "scripts": {
# "build": "rollup -c"
# }
# 然后执行:
npm run build
/rollup.config.js
// rollup.config.js
export default {
// 入口文件
input: 'src/index.js',
// 输出配置(支持数组,输出多格式)
output: [
{
// ES 模块格式(推荐给现代项目使用)
file: 'dist/index.es.js',
format: 'es',
// 生成源码映射(方便调试)
sourcemap: true
},
{
file: 'dist/index.iife.js',
format: 'iife',
sourcemap: false
}
]
};
/src/XpathUtil.js
/**
* 获取单个节点
* @param {string} expression - XPath表达式
* @param {Node} contextNode - 上下文节点(默认document)
* @returns {Element|null} 匹配的节点,无则返回null
*/
function getSingleNode(expression, contextNode = document) {
if (typeof expression !== 'string' || expression.trim() === '') {
console.error('XPath表达式必须是非空字符串');
return null;
}
try {
const result = document.evaluate(
expression,
contextNode,
null,
XPathResult.FIRST_ORDERED_NODE_TYPE,
null
);
return result.singleNodeValue || null;
} catch (error) {
console.error('XPath解析失败:', error.message);
return null;
}
}
/**
* 获取多个节点
* @param {string} expression - XPath表达式
* @param {Node} contextNode - 上下文节点(默认document)
* @returns {Element[]} 匹配的节点数组,无则返回空数组
*/
function getNodes(expression, contextNode = document) {
if (typeof expression !== 'string' || expression.trim() === '') {
console.error('XPath表达式必须是非空字符串');
return [];
}
try {
const result = document.evaluate(
expression,
contextNode,
null,
XPathResult.ORDERED_NODE_ITERATOR_TYPE,
null
);
const nodes = [];
let currentNode;
while ((currentNode = result.iterateNext())) {
nodes.push(currentNode);
}
return nodes;
} catch (error) {
console.error('XPath解析失败:', error.message);
return [];
}
}
/**
* 获取节点的文本内容
* @param {string} expression - XPath表达式
* @param {Node} contextNode - 上下文节点(默认document)
* @returns {string} 文本内容,无则返回空字符串
*/
function getText(expression, contextNode = document) {
const node = getSingleNode(expression, contextNode);
return node ? (node.textContent || '').trim() : '';
}
/**
* 获取节点的属性值
* @param {string} expression - XPath表达式
* @param {string} attrName - 属性名
* @param {Node} contextNode - 上下文节点(默认document)
* @returns {string} 属性值,无则返回空字符串
*/
function getAttribute(expression, attrName, contextNode = document) {
const node = getSingleNode(expression, contextNode);
return node ? (node.getAttribute(attrName) || '').trim() : '';
}
/**
* 批量提取数据(适用于列表类场景,如电影列表)
* @param {string} listExpression - 列表项的XPath表达式
* @param {Object} fieldMap - 字段映射(key: 字段名, value: 相对XPath)
* @param {Node} contextNode - 上下文节点(默认document)
* @returns {Array<Object>} 提取的数据数组
*/
function extractListData(listExpression, fieldMap, contextNode = document) {
const listNodes = getNodes(listExpression, contextNode);
return listNodes.map(node => {
const item = {};
for (const [field, expr] of Object.entries(fieldMap)) {
// 相对路径:以当前列表项为上下文
if (expr.startsWith('@')) {
// 提取当前节点的属性
item[field] = node.getAttribute(expr.slice(1)) || '';
} else if (expr.includes('text()')) {
// 提取文本
item[field] = getText(expr, node);
} else {
// 提取子节点文本
item[field] = getText(expr, node);
}
}
return item;
});
}
export default {
getSingleNode,
getNodes,
getText,
getAttribute,
extractListData
};
/src/index.js
import XPathUtil from './XpathUtil.js'
// ==================== 浏览器环境使用示例 ====================
// 1. 获取单个节点文本(比如豆瓣电影首页的标题)
const pageTitle = XPathUtil.getText('//title');
console.log('页面标题:', pageTitle);
// 2. 获取单个节点属性(比如某部电影的封面图src)
const coverSrc = XPathUtil.getAttribute('//img[@class="movie-cover"]', 'src');
console.log('封面图地址:', coverSrc);
// 3. 获取多个节点(比如所有热门电影的标题)
const movieTitles = XPathUtil.getNodes('//div[@class="hot-movie"]/h3')
.map(node => node.textContent.trim());
console.log('热门电影:', movieTitles);
// 4. 批量提取电影列表数据(核心场景)
const movies = XPathUtil.extractListData(
'//div[@class="movie-item"]', // 列表项XPath
{
id: '@data-id', // 提取当前节点的data-id属性
title: './h3[@class="title"]', // 提取子节点标题
rating: './span[@class="rating"]', // 提取评分
director: './p[@class="director"]/text()' // 提取导演文本
}
);
console.log('电影列表数据:', movies);