1、通过开发Vue CLI插件来修改@vue/cli创建的项目
如果你想改变@vue/cli创建的项目的一些配置,首先可以找一找有没有这样的Vue CLI插件。如果没有,相比于写成一个普通的命令行工具,不如把它写成一个Vue CLI插件。
写成Vue CLI插件的好处是遵循Vue CLI插件规范,可以让你的工具成为Vue CLI生态的一员,借助Vue的庞大用户群体,为更多面临同样场景的开发者有提供针对性的服务。
Vue CLI插件遵循 vue-cli-plugin-<name> 或者 @scope/vue-cli-plugin-<name> 这样的命名惯例,这样,它能够被 @vue/cli-service 发现和被其他开发者通过搜索发现,并可通过 vue add <name> 或者 vue invoke <name> 安装。
Vue CLI插件可以修改项目的什么内容呢?
根据Vue CLI插件开发指南的介绍,主要包括如下方面:
1)修改项目的 webpack 配置
例如,为特定的文件扩展名添加新的 webpack 解析规则。像@vue/cli-plugin-typescript就是为.ts 和 .tsx 文件添加webpack解析规则;
2)添加新的 vue-cli-service 命令
例如,@vue/cli-plugin-unit-jest 添加了 test:unit 命令,允许开发者运行单元测试;
3)扩展 package.json
4)在项目中创建新文件、或者修改老文件。
有时创建一个示例组件或者通过给入口文件(main.js)添加导入(imports)是一个好的主意;
5)提示用户选择一个特定的选项
例如,你可以询问用户是否创建我们前面提到的示例组件。
通常,一个Vue CLI的目录结构如下:
.
├── README.md
├── generator.js # generator(可选)
├── index.js # service 插件
├── package.json
├── prompts.js # prompt 文件(可选)
└── ui.js # Vue UI 集成(可选)
当然,Vue CLI插件开发指南中也特别指出:
不要过度使用 vue-cli 插件!如果你仅希望包含特定的插件,例如,Lodash - 相比创建一个特定的插件,通过 npm 手动安装更加简单。
2、通过创建Vue CLI的远程Preset来实现类似项目脚手架的功能
有的时候,光修改一些简单的配置可能还解决不了问题。因为有时候你实际是需要创建一个项目脚手架。
参考Vue CLI的远程Preset的官方文档,我们可以可以通过发布 git repo,然后通过如下命令实现基于该repo来创建项目——这个git repo就相当于项目的模板:
# 从 GitHub repo 使用 preset
vue create --preset username/repo my-project
通过这种方式,我们可以轻松地利用Vue-CLI工具的能力,轻松地实现类似传统脚手架所完成的工作。
如下所示,是一个preset项目的目录结构:
.
├─.gitignore
├─CHANGELOG.md
├─CONTRIBUTE.md
├─package.json
├─preset.json
├─prompts.js
├─README.md
├─TODO.md
├─yarn.lock
└─generator
├─index.js
└─template
├─babel.config.js
├─jest.config.js
├─jsconfig.json
├─postcss.config.js
├─vue.config.js
├─_editorconfig
├─_env
├─_env.development
├─_env.preview
├─_prettierrc
└─src
其核心项目创建逻辑在./generator/indes.js文件中:
module.exports = (api, options, rootOptions) => {
// 扩展package.json
api.extendPackage({
scripts: {
……
},
dependencies: {
……
},
devDependencies: {
……
},
gitHooks: {
……
}
})
// 先删除 vue-cli4 的默认目录
api.render(files => {
Object.keys(files)
.filter(path => path.startsWith('src/') || path.startsWith('public/'))
.forEach(path => delete files[path])
})
// 再来基于项目模板生成项目所需要的文件
api.render('./template')
// 禁止默认README.md文件生成
api.onCreateComplete(() => {
process.env.VUE_CLI_SKIP_WRITE = true
})
}
其中,./template文件夹下放的就是项目的模板文件。该目录下以下划线(_)开头的文件,最终都会转成以点号(.)开头。
基于Vue CLI远程preset创建项目的具体方法如下:
npm i -g @vue/cli #安装 vue-cli 4.x
vue create --preset direct:git@github.com:xxx/xxx-preset.git --clone <project-name>
cd <project-name>
yarn run serve #本地预览所创建的项目
3、基于Vuepress创建自己的项目文档初始化工具,统一各项目的文档。
一般来说,一个比较规范的项目文档会包含如下内容:
- 指南
- API参考
- 常见问题
- 应用案例
- 更新日志
- 参与贡献
- 切换版本(0.x/1.x/2.x……)
- Github 或者 Gitlab
- 切换语言(中文/En……)
希望实现的大体效果如下:
怎么实现呢?
我们参照vuepress-next的源码的docs目录下的内容,创建一个项目命名为doc-template,目录结构如下,作为模板:
.
└─docs
├─.vuepress
│ ├─public # 放置图片
│ ├─configs
│ │ ├─navbar # 顶部导航配置
│ │ | ├─index.ts
│ │ | ├─zh.ts
│ │ | └─en.ts
│ │ └─sidebar # 左侧导航配置
│ │ ├─index.ts
│ │ ├─zh.ts
│ │ └─en.ts
│ ├─styles # 样式配置
│ │ ├─index.styl
│ │ └─palette.styl # 主题样式的变量配置
│ └─theme
│ └─index.ts
├─README.md
├─api
│ └─README.md
├─application-cases
│ └─README.md
├─contributing
│ └─README.md
├─faq
│ └─README.md
├─guide
│ └─README.md
├─release-notes
│ └─README.md
└─en # 放置英文文档
├─README.md
├─api
| └─README.md
├─application-cases
| └─README.md
├─contributing
| └─README.md
├─faq
| └─README.md
├─guide
| └─README.md
└─release-notes
└─README.md
然后我们再创建另外一个命令行项目命名为doc-cli,在其中实现一个命令doc-cli init <project-name>,其功能为以上面的doc-template为模板创建文档项目。
其功能非常简单:
1)利用commander模块实现命令行
2)利用inquirer模块接收控制台的输入
3)下载doc-template这个模板仓库中的git代码
4)读出相关文件的内容,通过handlebars这个模板引擎模块的compile方法进行处理,并把数据渲染到模板中去,最后再把处理后的文件内容写回到项目文件中,就得到了我们想要的文档项目。
const program = require('commander');
const inquirer = require('inquirer');
const download = require('download-git-repo');
const handlebars = require('handlebars');
program
.version('1.0.0', '-v, --version')
.command('init <project-name>')
.action((projectName) => {
if (!fs.existsSync(projectName)) {
// inquier接收参数
inquirer
.prompt([
{
name: 'description',
type: 'input',
message: '请输入项目描述',
}
])
.then((answers) => {
const destinationDir = projectName;
const gitRepoURL = 'http://github.com/xxx/doc-template.git#master';
download(gitRepoURL, destinationDir, { clone: true }, (err) => {
if (erros) {
console.log('下载git仓库出错');
} else {
const packageJsonDir = `${destinationDir}/package.json`;
const data = {
name,
description: answers.description,
};
if (fs.existsSync(packageJsonDir)) {
const packageJsonContent = fs.readFileSync(packageJsonDir).toString();
const result = handlebars.compile(packageJsonContent)(data);
fs.writeFileSync(packageJsonDir, result);
}
}
}
})
} else {
console.log(chalk.red('该项目目录已存在'));
}
)
此时执行`npm run docs:dev'即可预览到效果,如下图所示,可以提供出中文和英文模板,把其中的xxx改成项目的内容,就得到了一份美观且结构严谨的文档。效率瞬间提高好几倍,而且风格也很一致!