『手撕Vue-CLI』编译模板『下』

2024-05-27 01:33:28 浏览数 (1)

前言

经『手撕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') 判断是否是模板文件,如果是模板文件,就将文件内容打印出来,内容如下图所示:

接下来需要在判断一下当前文件的内容是否需要编译可以用是否包含 <% 来判断,如果包含 <% 就需要编译,否则就不需要编译。

代码语言:javascript复制
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 版本。

代码语言:shell复制
npm install consolidate@0.15.1

导入 consolidate.ejs.render 方法:

代码语言:javascript复制
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 库。

代码语言:shell复制
npm install ejs

然后再次使用 nue-cli create 创建编译模板项目,编译成功了,内容如下图所示:

我正在参与2024腾讯技术创作特训营最新征文,快来和我瓜分大奖!

0 人点赞