UNPKG

webpack-routes-plugin

Version:

基于文件系统的webpack约定式路由插件 - 自动生成路由配置,告别手写路由文件

180 lines (158 loc) 4.4 kB
const path = require('path'); /** * 标准化路由路径 * @param {string} routePath - 原始路由路径 * @returns {string} 标准化后的路由路径 */ function normalizeRoutePath(routePath) { if (!routePath || routePath === '/') { return '/'; } // 确保以 / 开头 if (!routePath.startsWith('/')) { routePath = '/' + routePath; } // 移除尾部的 / if (routePath.endsWith('/') && routePath.length > 1) { routePath = routePath.slice(0, -1); } // 处理多个连续的 / routePath = routePath.replace(/\/+/g, '/'); return routePath; } /** * 获取相对路径 * @param {string} from - 起始路径 * @param {string} to - 目标路径 * @returns {string} 相对路径 */ function getRelativePath(from, to) { const fromDir = path.dirname(from); let relativePath = path.relative(fromDir, to); // 在Windows系统上,将反斜杠转换为正斜杠 relativePath = relativePath.replace(/\\/g, '/'); // 确保相对路径以 ./ 开头 if (!relativePath.startsWith('./') && !relativePath.startsWith('../')) { relativePath = './' + relativePath; } return relativePath; } /** * 检查是否为有效的页面文件 * @param {string} filename - 文件名 * @param {string[]} extensions - 允许的文件扩展名 * @returns {boolean} 是否为有效的页面文件 */ function isValidPageFile(filename, extensions) { const ext = path.extname(filename); return extensions.includes(ext); } /** * 将文件路径转换为驼峰命名 * @param {string} filepath - 文件路径 * @returns {string} 驼峰命名的字符串 */ function toCamelCase(filepath) { return filepath .replace(/[-_\s]+(.)?/g, (_, c) => c ? c.toUpperCase() : '') .replace(/[^a-zA-Z0-9]/g, ''); } /** * 获取路由的权重,用于排序 * @param {string} routePath - 路由路径 * @returns {number} 路由权重 */ function getRouteWeight(routePath) { let weight = 0; // 静态路由权重更高 if (!routePath.includes(':')) { weight += 1000; } // 路径段数越多权重越高 const segments = routePath.split('/').filter(Boolean); weight += segments.length * 100; // 每个静态段增加权重 segments.forEach(segment => { if (!segment.startsWith(':')) { weight += 10; } }); return weight; } /** * 检查路径是否匹配排除模式 * @param {string} filepath - 文件路径 * @param {string[]} excludePatterns - 排除模式数组 * @returns {boolean} 是否匹配排除模式 */ function shouldExclude(filepath, excludePatterns) { return excludePatterns.some(pattern => { if (pattern.includes('*')) { // 支持简单的通配符 const regex = new RegExp(pattern.replace(/\*/g, '.*')); return regex.test(filepath); } return filepath.includes(pattern); }); } /** * 提取动态路由参数 * @param {string} routePath - 路由路径 * @returns {string[]} 参数数组 */ function extractDynamicParams(routePath) { const params = []; const matches = routePath.match(/:([a-zA-Z_$][a-zA-Z0-9_$]*)/g); if (matches) { matches.forEach(match => { params.push(match.substring(1)); }); } return params; } /** * 生成路由名称 * @param {string} routePath - 路由路径 * @returns {string} 路由名称 */ function generateRouteName(routePath) { return routePath .replace(/^\//, '') .replace(/\//g, '-') .replace(/:/g, '') .replace(/-+/g, '-') .replace(/^-|-$/g, '') || 'home'; } /** * 检查是否为布局文件 * @param {string} filename - 文件名 * @returns {boolean} 是否为布局文件 */ function isLayoutFile(filename) { const layoutNames = ['_layout', 'layout', '_app']; const nameWithoutExt = path.basename(filename, path.extname(filename)); return layoutNames.includes(nameWithoutExt); } /** * 检查是否为错误页面 * @param {string} filename - 文件名 * @returns {boolean} 是否为错误页面 */ function isErrorPage(filename) { const errorPages = ['404', '500', '_error', 'error']; const nameWithoutExt = path.basename(filename, path.extname(filename)); return errorPages.includes(nameWithoutExt); } module.exports = { normalizeRoutePath, getRelativePath, isValidPageFile, toCamelCase, getRouteWeight, shouldExclude, extractDynamicParams, generateRouteName, isLayoutFile, isErrorPage };