新建一个组件库模板
发布一个npm包
js
git clone https://github.com/imooc-lego/lego-components.git
cd lego-components/
//用cnpm会报错
npm i
// 启动项目
npm run serve
将lego-components
放至mj-cli-dev-template/mj-cli-dev-lego-components/template
目录下;
修改tempalte文件夹里的package.json为ejs模板;
template/package.json
{
"name": "<%= className %>",
"version": "<%= version %>"
}
template文件夹同级的package.json修改:
js
{
"name": "mj-cli-dev-lego-compoments",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC"
}
接着npm publish
这个mj-cli-dev-lego-compoments
包;
mongodb插入一条数据
我这里是用命令插入数据的;增加一个tag
的标志,分为project和component;还可以增加一个ignore
字段,是用来ejs模板转换时忽略某些文件;
js
db.project.insert({name: '乐高组件库模版',
npmName: 'mj-cli-dev-lego-compoments',
version: '1.0.0',
type: 'normal',
tag: ['component'],
installCommand: 'npm install --registry=https://registry.npm.taobao.org',
startCommand: 'npm run serve',
ignore: '**/public/**'
})
项目和组件模版数据隔离
根据项目和组件的选择对数据做筛选;
js
// getProjectInfo方法
this.template = this.template.filter((template) =>
template.tag.includes(type)
);
从接口获取ignore进行拼装;
js
//installNormalTemplate方法
const opts = {
ignore: ["**/node_modules/**"],
};
if (this.templateInfo.ignore) {
opts.ignore = opts.ignore.concat(this.templateInfo.ignore);
}
获取组件信息功能
组件和项目的逻辑基本一致;组件比项目多一个输入描述信息的命令;
先来修改一下mj-cli-dev-lego-components/template/package.json文件中;
js
"description": "<%= description %>"
// 删除files,它会限制上传的文件数量
然后发布mj-cli-dev-lego-components@1.0.1
版本;
安装模板时会报错,如下图:
这里我们可以在ignore中去忽略png格式的文件,修改一下mongodb中的数据;
js
db.project.update({'name':'乐高组件库模版'},{$set:{'ignore': ['**/public/**', '**.png']}})
此时已经成功启动项目了;
自定义模板开发
在mj-cli-dev-template/mj-cli-dev-template-custom-vue3目录下复制一份mj-cli-dev-template-vue3;可以去本地install的目录地址下本地调试mj-cli-dev-template-custom-vue3
模板的代码;最后将调试成功的代码发布npm;
mj-cli-dev-template-custom-vue3/package.json
{
"name": "mj-cli-dev-template-custom-vue3",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC"
}
创建mj-cli-dev-template-custom-vue3/index.js文件;
mj-cli-dev-template-custom-vue3/index.js
const fse = require("fs-extra");
const inquirer = require("inquirer");
const ejs = require("ejs");
async function ejsRender(options) {
const dir = options.targetPath;
const { projectInfo } = options;
return new Promise((resolve, reject) => {
require("glob")(
"**",
{
cwd: dir,
ignore: options.ignore,
nodir: true,
},
(err, files) => {
if (err) {
reject(err);
}
Promise.all(
files.map((file) => {
const filePath = path.join(dir, file);
return new Promise((resolve1, reject1) => {
ejs.renderFile(filePath, projectInfo, {}, (err, result) => {
if (err) {
reject1(err);
} else {
// ejs模板转换不成功,渲染结果需重新写入
fse.writeFileSync(filePath, result);
resolve1(result);
}
});
});
})
)
.then(() => {
resolve();
})
.catch((err) => {
reject(err);
});
}
);
});
}
async function install(options) {
const projectPrompt = [];
const descriptionPrompt = {
type: "input",
name: "componentDescription",
message: "请输入项目描述信息",
default: "",
validate: function (v) {
const done = this.async();
setTimeout(function () {
if (!v) {
done("请输入项目描述信息");
return;
} else {
done(null, true);
}
}, 0);
},
};
projectPrompt.push(descriptionPrompt);
const obj = await inquirer.prompt(projectPrompt);
options.projectInfo.description = obj.componentDescription;
try {
//拷贝模版代码至当前目录
const { sourcePath, targetPath } = options;
// 确保目录存在,不存在会创建一个
fse.ensureDirSync(sourcePath);
fse.ensureDirSync(targetPath);
fse.copySync(sourcePath, targetPath);
const opts = {
ignore: ["**/node_modules/**"],
targetPath,
projectInfo: options.projectInfo,
};
if (options.templateInfo.ignore) {
opts.ignore = opts.ignore.concat(options.templateInfo.ignore);
}
await ejsRender(opts);
} catch (e) {
throw e;
}
}
module.exports = install;
mj-cli-dev-template-custom-vue3/template/package.json
{
"name": "<%= className %>",
"version": "<%= version %>",
"description": "<%= description %>",
npm publish
新的包mj-cli-dev-template-custom-vue3
;
mongodb中插入一条数据:
js
db.project.insert({name: 'vue3自定义模板',
npmName: 'mj-cli-dev-template-custom-vue3',
version: '1.0.0',
type: 'custom',
tag: ['project'],
installCommand: 'cnpm install',
startCommand: 'npm run serve',
ignore: ['**/public/**']
})