UNPKG

webpack-routes-plugin

Version:

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

99 lines (83 loc) 3.13 kB
const path = require('path'); const fs = require('fs'); const RouteGenerator = require('./RouteGenerator'); class WebpackRoutesPlugin { constructor(options = {}) { this.options = { // 页面文件目录,默认为 pages pagesDir: options.pagesDir || 'src/pages', // 生成的路由文件路径 outputPath: options.outputPath || 'src/routes.js', // 文件扩展名 extensions: options.extensions || ['.js', '.jsx', '.ts', '.tsx'], // 是否包含子目录 includeSubdirectories: options.includeSubdirectories !== false, // 排除的文件或目录 exclude: options.exclude || [], // 自定义路由配置 customRoutes: options.customRoutes || [], // 是否生成TypeScript类型定义 generateTypes: options.generateTypes || false, ...options }; this.routeGenerator = new RouteGenerator(this.options); } apply(compiler) { const pluginName = 'WebpackRoutesPlugin'; // 在编译开始前生成路由 compiler.hooks.beforeRun.tapAsync(pluginName, (compilation, callback) => { this.generateRoutes(callback); }); // 在监听模式下,每次重新编译时生成路由 compiler.hooks.watchRun.tapAsync(pluginName, (compilation, callback) => { this.generateRoutes(callback); }); // 监听页面文件变化 if (compiler.options.mode === 'development') { compiler.hooks.afterCompile.tap(pluginName, (compilation) => { const pagesDir = path.resolve(compiler.context, this.options.pagesDir); this.addDirectoryDependency(compilation, pagesDir); }); } } generateRoutes(callback) { try { console.log('🚀 正在生成约定式路由...'); const routes = this.routeGenerator.generateRoutes(); const outputPath = path.resolve(process.cwd(), this.options.outputPath); // 确保输出目录存在 const outputDir = path.dirname(outputPath); if (!fs.existsSync(outputDir)) { fs.mkdirSync(outputDir, { recursive: true }); } // 写入路由文件 fs.writeFileSync(outputPath, routes); console.log(`✅ 路由文件已生成: ${outputPath}`); if (callback) callback(); } catch (error) { console.error('❌ 生成路由时发生错误:', error); if (callback) callback(error); } } addDirectoryDependency(compilation, directory) { if (fs.existsSync(directory)) { compilation.fileDependencies.add(directory); // 递归添加子目录依赖 const addSubdirectories = (dir) => { const items = fs.readdirSync(dir); items.forEach(item => { const fullPath = path.join(dir, item); const stat = fs.statSync(fullPath); if (stat.isDirectory()) { compilation.fileDependencies.add(fullPath); addSubdirectories(fullPath); } else { compilation.fileDependencies.add(fullPath); } }); }; addSubdirectories(directory); } } } module.exports = WebpackRoutesPlugin;