Webpack打包Express SSR应用时readdirSync动态加载路由文件无法识别咨询
问题1:将动态路由文件打包进bundle.js的方案
可以实现,核心是让webpack识别动态require的上下文,自动将所有路由文件纳入打包范围,操作如下:
- 在
webpack.server.js中引入webpack本身,新增ContextReplacementPlugin插件配置,指定动态require的扫描范围:
// 顶部新增引入 const webpack = require('webpack') const config = { // 原有配置保留,新增plugins字段(如果已有则合并) plugins: [ new webpack.ContextReplacementPlugin( // 匹配动态require的路径前缀 /\/src\/routes/, // 指定路由文件所在的实际源码目录 path.resolve(__dirname, 'src/routes'), true, // 匹配需要打包的路由文件后缀 /\.(js|jsx|ts|tsx)$/ ) ], // 建议补充resolve配置,避免路径识别异常 resolve: { alias: { '/src/routes': path.resolve(__dirname, 'src/routes') }, extensions: [".js", ".jsx", ".json", ".ts", ".tsx"] } }
- 配置生效后,webpack构建时会自动把
src/routes下所有符合后缀的文件打包进bundle.js,运行时动态require会直接加载bundle内的模块,不会再读取本地文件系统,也就不会报目录不存在的错误。
问题2:单独编译路由文件输出到对应目录的方案
如果上述方案不适用,可以配置webpack多入口单独编译路由文件,操作如下:
- 改造
webpack.server.js的entry配置,自动读取所有路由文件作为独立入口:
// 顶部新增引入fs const fs = require('fs') // 生成路由文件的入口配置 const routeEntry = {} const routePath = path.resolve(__dirname, 'src/routes') fs.readdirSync(routePath).forEach(file => { if (/\.(js|jsx|ts|tsx)$/.test(file)) { // 入口key保持和原路径一致,保证输出目录结构匹配 routeEntry[`src/routes/${file}`] = path.join(routePath, file) } }) const config = { // 原有entry配置修改,合并路由入口 entry: { main: "./app.ts", ...routeEntry }, // 原有output配置修改,保持输出路径和入口key一致 output: { libraryTarget: "commonjs", path: path.join(__dirname, "build"), filename: "[name].js", }, resolve: { // 建议补充.tsx后缀,避免TSX路由文件识别失败 extensions: [".js", ".jsx", ".json", ".ts", ".tsx"] }, // 其他原有配置保留 }
- 构建后会在
build/src/routes/目录下生成所有编译后的路由文件,既符合原有代码的读取逻辑,路由文件也经过了babel编译支持JSX/ES6+语法。
内容的提问来源于stack exchange,提问作者aviadch
相关产品推荐
相关产品推荐

