如何通过html-webpack-plugin加载JSON文件传入Handlebars模板?
当然可以!这其实是html-webpack-plugin结合Handlebars非常实用的一个用法,正好能帮你把数据和模板彻底分离,避免模板文件臃肿。下面是具体的实现方案:
核心思路
通过Node.js的fs模块读取JSON数据文件,然后在HtmlWebpackPlugin的配置中,将数据注入到Handlebars模板的上下文里,这样模板就能直接调用这些数据了。
步骤1:调整Webpack配置
假设你的JSON数据文件放在src/data/目录下,并且和页面文件一一对应(比如index.hbs对应index.json),可以修改你现有配置中的plugins部分:
const path = require('path'); const fs = require('fs'); const CleanWebpackPlugin = require('clean-webpack-plugin'); const HtmlWebpackPlugin = require('html-webpack-plugin'); const ExtractTextPlugin = require('extract-text-webpack-plugin'); const webpack = require('webpack'); const extractCss = new ExtractTextPlugin({ filename: './css/app.css' }); const pages = fs .readdirSync(path.resolve(__dirname, 'src/hbs/pages')) .filter(fileName => fileName.endsWith('.hbs')); // 定义数据文件的根目录 const dataRoot = path.resolve(__dirname, 'src/data'); module.exports = { // ... 你的其他配置 plugins: [ new CleanWebpackPlugin(['build']), extractCss, ...pages.map(page => { // 提取页面文件名(去掉.hbs后缀) const pageBaseName = path.basename(page, '.hbs'); // 读取对应JSON数据,无文件时用空对象兜底 let pageData = {}; try { const dataFilePath = path.join(dataRoot, `${pageBaseName}.json`); pageData = JSON.parse(fs.readFileSync(dataFilePath, 'utf8')); } catch (err) { console.warn(`⚠️ 未找到页面 ${pageBaseName} 的数据文件,将使用空数据`); } return new HtmlWebpackPlugin({ template: `hbs/pages/${page}`, filename: page, // 将数据注入模板上下文(v4+版本用templateParameters,旧版本可用data字段) templateParameters: { pageData: pageData, // 还可以在这里添加全局通用数据,比如站点信息 globalData: JSON.parse(fs.readFileSync(path.join(dataRoot, 'global.json'), 'utf8')) } }); }) ], // ... 你的其他配置 };
步骤2:在Handlebars模板中使用数据
比如你的index.json内容是:
{ "list": ["Item 1", "Item 2", "Item 3"] }
那么在index.hbs里就可以这样调用数据:
<h1>{{globalData.siteTitle}}</h1> <ul> {{#each pageData.list}} <li>{{this}}</li> {{/each}} </ul>
注意事项
- JSON格式校验:确保你的JSON文件格式正确,否则
JSON.parse会抛出错误,建议用try-catch处理文件不存在或格式错误的情况。 - 版本兼容:如果你的
html-webpack-plugin是v3及以下版本,需要把templateParameters换成data字段,模板中直接访问数据属性即可(比如{{list}})。 - 全局数据复用:如果有多个页面共用的数据,可以单独放在一个
global.json里,在配置顶部提前读取并注入所有模板。
内容的提问来源于stack exchange,提问作者Gregor
相关产品推荐
相关产品推荐

