基于Vue.js技术栈的几种项目工具打造

689 阅读5分钟

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改成项目的内容,就得到了一份美观且结构严谨的文档。效率瞬间提高好几倍,而且风格也很一致!