自定义项目模板开发
在haha-cli-dev-template 这个模块下,新建模板 haha-cli-dev-template-custom-vue3。
修改 package.json , 添加 main 字段
“main”: “index.js”
添加 index.js
function install(options) { console.log(options); } module.exports = install 复制代码
发布到 npm
数据库添加一条新的数据
自定义模板安装逻辑开发
const log = require('npmlog')const fse = require('fs-extra')const ejs = require('ejs')let targetPathasync function install(options) {try {const templatePath = options.templatePathconst dirs = fs.readdirSync(templatePath)const filePath = path.resolve(templatePath, dirs[0])targetPath = path.resolve(process.cwd(), options.projectInfo.project)fse.ensureDirSync(filePath)fse.ensureDirSync(targetPath)fse.copySync(filePath, targetPath)} catch (error) {throw error} finally {log.info('模板安装成功')}const ignore = ['**/node_modules/**', ...options.template?.ignore.split(',')]await ejsRender(ignore, options)}//ejs渲染=>将模板中的转成模板中package.json定义的版本function ejsRender(ignore, options) {return new Promise((resolve, reject) => {//得到文件夹下除去ignore的所有路径,require('glob')('**',{ignore,cwd: targetPath,nodir: true},(err, files) => {if (err) {reject(err)}Promise.all(files.map(file => {//得到每一个文件的具体路径const filePath = path.join(targetPath, file)return new Promise((resolve1, reject1) => {//解析文件ejs.renderFile(filePath, options.projectInfo, {}, function (err, str) {if (err) {reject1(err)} else {//使用renderFile得到的str是字符串,需要转成文件fse.writeFileSync(filePath, str)resolve1(str)}})})})).then(() => resolve(files)).catch(err => reject(err))})})}module.exports = install
...//记得加上bundledDependencies 打包的时候将以下的插件打包进入 或者将这些包写入dependencies 生成环境使用(推荐)"bundledDependencies": ["npmlog","fs-extra","glob","ejs"]
...//自定义安装async installCustomTemplate() {if (await this.pkg.exists()) {const rootFile = this.pkg.getRootFilePath()if (fs.existsSync(rootFile)) {const templatePath = path.resolve(this.pkg.cacheFilePath, 'template')const options = { templatePath, projectInfo: this.projectInfo, template: this.template }const code = `require('${rootFile}')(${JSON.stringify(options)})`const ret = await execAysnc('node', ['-e', code], {cwd: process.cwd(), //cwd 子进程的当前工作目录stdio: 'inherit' //inherit 将相应的stdio传给父进程或者从父进程传入,相当于process.stdin,process.stout和process.stderr})if (ret === 0) {log.success('命令执行成功')} else {throw new Error('命令执行成功失败')}}}}

