前言
经『手撕Vue-CLI』编译模板『上』已经将大概流程编写好了,接下来就是将模板中的变量替换成用户输入的内容。
让用户填写配置信息
在 vue-advanced-template
模板中,有一个 ask.js
文件,这个文件是用来获取用户输入的信息的,这个文件的内容已经给大家查看过了,所以这里就不再赘述。
直接编写实现代码:
代码语言:javascript复制.use(async (files, metal, done) => {
// 获取元数据
const args = require(askPath);
// 执行询问
const result = inquirer.prompt(args);
// 将询问的结果挂载到 metal.metadata() 上,这样在下一个插件中就可以获取到询问的结果
const data = await result;
const meta = metal.metadata();
Object.assign(meta, data);
done();
})
.use(async (files, metal, done) => {
// 从 metal.metadata() 获取到用户输入的数据
const meta = metal.metadata();
console.log(meta);
done();
})
这里通过 inquirer.prompt(args)
获取到用户输入的数据,然后将这个数据挂载到 metal.metadata()
上,这样在下一个插件中就可以获取到用户输入的数据了。
替换模板中的变量
在 vue-advanced-template
模板中,有一个 package.json
文件,这个文件是用来替换模板中的变量的,这个文件的内容已经给大家查看过了,里面写的是 ejs 的语法,所以这里就不再赘述。
先根据 files 过滤出是否是模板文件,如果是模板文件,就将文件内容替换成用户输入的内容。
代码语言:javascript复制Reflect.ownKeys(files).forEach(async (file) => {
// 判断是否是模板文件
if (file.includes('js') || file.includes('json')) {
console.log(files[file].contents.toString());
}
});
这里通过 Reflect.ownKeys(files)
获取到所有的文件名,然后通过 file.includes('js') || file.includes('json')
判断是否是模板文件,如果是模板文件,就将文件内容打印出来,内容如下图所示:
接下来需要在判断一下当前文件的内容是否需要编译可以用是否包含 <%
来判断,如果包含 <%
就需要编译,否则就不需要编译。
Reflect.ownKeys(files).forEach(async (file) => {
// 判断是否是模板文件
if (file.includes('js') || file.includes('json')) {
// 判断是否需要编译
if (files[file].contents.toString().includes('<%')) {
console.log(files[file].contents.toString());
}
}
});
到这里就可以拿到具体的文件了,那么问题来了如何替换呢?这里需要用到一个 consolidate
库,这个库是用来编译模板的,这里使用 consolidate.ejs.render
方法来编译模板。
先安装 consolidate
库,这里我不采用最新版本,因为我不使用 ES6 的语法,所以我安装 consolidate@0.15.1
版本。
npm install consolidate@0.15.1
导入 consolidate.ejs.render
方法:
let {render} = require('consolidate').ejs;
render = promisify(render);
这里使用 promisify
方法将 render
方法转换成 Promise
方法,这样就可以使用 await
来等待编译结果了。
接下来的代码我就一步到位了,直接上代码:
代码语言:javascript复制Reflect.ownKeys(files).forEach(async (file) => {
// 判断是否是模板文件
if (file.includes('js') || file.includes('json')) {
// 判断是否需要编译
const fileContent = files[file].contents.toString();
if (fileContent.includes('<%')) {
const result = await consolidate.ejs.render(fileContent, meta);
files[file].contents = Buffer.from(result);
}
}
});
这里通过 consolidate.ejs.render(fileContent, meta)
编译模板,然后将编译结果赋值给 files[file].contents
,这样就完成了模板的编译。
测试
当我进行使用 nue-cli create 创建编译模板项目时,出现 Error: Cannot find module 'ejs'
错误,这是因为 consolidate
库需要依赖 ejs
库,所以需要安装 ejs
库。
npm install ejs
然后再次使用 nue-cli create 创建编译模板项目,编译成功了,内容如下图所示:
我正在参与2024腾讯技术创作特训营最新征文,快来和我瓜分大奖!