Apache Velocity+Webpack项目中VM文件处理方案咨询
我之前在项目里也碰到过类似的需求,刚好研究过几个可行的方案,分享给你参考:
方案1:自定义Webpack Loader(最灵活可控)
Webpack的核心逻辑就是用Loader处理不同类型的文件,既然没有现成的VM注释移除插件,自己写个简易Loader其实非常快,核心就是用正则匹配并移除VM的注释语法(VM单行注释是## 内容,多行注释是#* 内容 *#)。
步骤如下:
- 在项目根目录新建一个
vm-comment-remover-loader.js文件,内容如下:
module.exports = function(source) { // 移除单行注释:匹配##开头到行尾的内容 let processedContent = source.replace(/##.*$/gm, ''); // 移除多行注释:匹配#*开头到*#结尾的跨行内容 processedContent = processedContent.replace(/#\*[\s\S]*?\*#/g, ''); // 返回处理后的模板内容 return processedContent; };
- 在Webpack配置文件中添加这个Loader的规则:
module.exports = { module: { rules: [ { test: /\.vm$/, use: [ // 如果需要同时编译VM模板,可以在这里添加其他Velocity相关Loader,比如velocity-loader './vm-comment-remover-loader.js' ] } ] } };
如果你的VM模板里有类似注释格式的字符串内容(比如"## 这是用户输入的文本"),基础正则会误删,这时候可以借助velocityjs包解析AST来精准处理:
- 先安装依赖:
npm install velocityjs --save-dev - 修改Loader代码:
const velocity = require('velocityjs'); module.exports = function(source) { // 解析VM生成AST const ast = velocity.parse(source); // 过滤掉所有注释类型的节点 const filteredAst = ast.filter(node => node.type !== 'Comment'); // 将过滤后的AST重新转为VM模板内容 return velocity.stringify(filteredAst); };
方案2:基于现有Velocity Loader扩展
如果你的项目已经在用velocity-loader编译VM模板,可以把自定义的注释移除逻辑和它结合起来,Loader的执行顺序是从右到左,所以把注释移除Loader放在velocity-loader前面,先清注释再编译:
- 先安装
velocity-loader:
npm install velocity-loader --save-dev
- 配置Webpack规则:
module.exports = { module: { rules: [ { test: /\.vm$/, use: [ 'velocity-loader', './vm-comment-remover-loader.js' ] } ] } };
方案3:用Webpack插件批量处理(适合后期修改)
如果不需要在编译阶段处理,只是想在最终输出的文件里移除注释,可以写一个简单的Webpack插件,在文件输出前修改内容:
- 在项目里新建
vm-comment-remover-plugin.js:
class VMCommentRemoverPlugin { apply(compiler) { // 在emit阶段(文件即将输出时)触发 compiler.hooks.emit.tap('VMCommentRemoverPlugin', (compilation) => { // 遍历所有待输出的文件 Object.keys(compilation.assets).forEach(filename => { if (filename.endsWith('.vm')) { const originalSource = compilation.assets[filename].source(); // 移除注释逻辑和Loader里一致 let processedContent = originalSource.replace(/##.*$/gm, ''); processedContent = processedContent.replace(/#\*[\s\S]*?\*#/g, ''); // 更新文件内容 compilation.assets[filename] = { source: () => processedContent, size: () => processedContent.length }; } }); }); } } module.exports = VMCommentRemoverPlugin;
- 在Webpack配置里注册插件:
const VMCommentRemoverPlugin = require('./vm-comment-remover-plugin.js'); module.exports = { plugins: [ new VMCommentRemoverPlugin() ] };
这几个方案里,自定义Loader是最常用也最灵活的,如果你需要精准处理复杂的VM语法,推荐结合AST解析的方式~
内容的提问来源于stack exchange,提问作者Timur Misharin
相关产品推荐
相关产品推荐

