从零搭建自己的一个 vue-cli 项目

373 阅读5分钟

介绍

这是一个包含pc管理后台和移动端的uni-app集成cli项目,里面一些构建方法参考vben-admin,关于CLI项目如何在npm发布和迭代,可以参考我的这篇文章

  • pc管理后台: 由vue3 + vite + pinia + typescript + element-plus 搭建的简易后台管理系统。和它集成了unocss, threejs, echarts 等库,其中由antfu大神推出的unocss是最近上手使用很香的一个样式库,各位有兴趣的可以去github了解一下。项目里还安装了echartsthreejs不算常用的常用图形库,里面有简单的使用demo。

  • 移动端uni-app项目:由vue + vite + pinia + typescript + uview-plus 搭建的简易移动端项目。由于uni-app的vue3版本目前未有较成熟的开源UI库,uview-plus除了微信小程序,其他小程序的兼容性可能存在一些问题,如果涉及到支付宝或其他平台的小程序的项目请自行考虑后使用,uview-plus 官方文档地址

这两个项目均为开源,有兴趣的同学可以一起加入。

项目结构
├── build                      # 构建相关
├── public                     # 静态资源
│   │── favicon.ico            # favicon图标
├── src                        # 源代码
│   ├── api                    # 所有请求
│   ├── assets                 # 主题 字体等静态资源
│   ├── components             # 全局公用组件
│   ├── icons                  # 项目所有 svg icons
│   ├── hooks                  # 项目所有 hooks方法
│   ├── model                  # typescript 项目接口类型声明文件
│   ├── layout                 # 全局 layout
│   ├── router                 # 路由
│   ├── store                  # 全局 store管理
│   ├── styles                 # 全局样式
│   ├── types                  # 第三方typescript 类型文件
│   ├── utils                  # 全局公用方法
│   ├── static                 # 静态资源
│   ├── views                  # views 所有页面
│   ├── App.vue                # 入口页面
│   ├── main.js                # 入口文件 加载组件 初始化等
│   └── permission.js          # 权限管理
├── auto-imports.d.ts          # 根据unplugin-auto-import插件按需自动引入api
├── components.d.ts            # 项目按需自动导入组件配置
├── .env.xxx                   # 环境变量配置
├── .eslintrc.js               # eslint 配置项
├── .eslintrc-auto-import.json # unplugin-auto-import eslint配置项
├── index.html                 # html模板
├── vite.config.js             # vite 配置
├── postcss.config.js          # postcss 配置
└── package.json               # package.json

CLI 项目初始化

首先新建一个文件夹,初始化一个项目,构建项目所需要的 package.json 文件配置,这里根据实际需要去进行配置,完整 package.json 配置向可以在官方文档查看。

打开命令行工具,输入 npm init 进行参数配置, 项目名必填之外,其他的可以快速回车构建,最后 yes 就完事了。

package name: (test) my-cli-test          // 项目名称
version: (1.0.0)                          // 版本号
description: vue + vite templates         // 备注
entry point: (index.js)                   // 入口文件
test command: 
git repository: 
keywords: 
author: 
license: (ISC) 
About to write to /Users/lixue/code_boy/test/package.json:

{

  "name": "my-cli-test",
  "version": "1.0.0",
  "description": "test",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC"
}
Is this OK? (yes) yes

构建完之后就会在你的项目文件夹下生成一个 package.json 文件,同时也有必要建立一个Readme文件,介绍一下它的一些配置内容.

packagejson文件.png

CLI 项目搭建

  1. 新建一个入口文件,并在package.json中配置 bin 参数,它的作用有命令名和本地文件名的映射。全局安装此包时,该文件将链接到全局容器所在的位置,以便可以按名称运行。
"bin": {
    "vuezhao": "./vue-vite-zhao/index.js"
},
  1. 安装项目所需依赖
"dependencies": {
   "chalk": "^4.1.2",                   // 安装时的控制台提示
   "commander": "^8.2.0",               // 命令行自定义指令
   "download-git-repo": "^3.0.2",       // 下载模板项目
   "inquirer": "^8.1.5",                // 初始化项目时的填写步骤
   "ora": "4.0.5"                       // 下载时的进度提示loading
 }
  1. 功能构建
    • 创建项目模板,如果有多个模板,比如分别有pc端和移动端,可以依次加入

      const templates = {
       "templateName": {
         url: "你的项目仓库地址",
         downloadUrl: "direct:你的仓库地址#分支名称,ex:https://gitee.com/vue-zhao#master",
         description:
           "简单的介绍",
       }
      };
      
    • 配置自定义指令,这里获取package.json里的内容可以在我这篇文章里参考一下

      program
        .version(package.json内的版本号)
        .option("-i, --init", "初始化项目")
        .option("-V, --version", "查看版本号信息")
        .option("-l, --list", "查看可用模版列表");
      
    • 配置命令行填写步骤

    inquirer
    .prompt([
      {
        type: "input",
        name: "projectName",
        message: "请输入项目名称",
      },
      {
        type: "input",
        name: "description",
        message: "请输入项目简介",
      },
      {
        type: "list",
        name: "template",
        message: "选择其中一个作为项目模版",
        choices: [                                           // 这里的模板选择是根据上面的templates内容读取
          "templateName1 (vue+ts+vite项目模版)",
          "templateName2 (vue+ts+vite+uniapp 项目模板)"
        ],
      },
    ]).then((answers) => {
      // 把采集到的用户输入的数据解析替换到 package.json 文件中
      let url = templates[answers.template.split(" ")[0]].downloadUrl;
      initTemplateDefault(answers, url);
    });
    
    • 声明初始化方法
    async function initTemplateDefault(customContent, gitUrl) {
      console.log(
        chalk.bold.cyan("CosenCli: ") + "will creating a new project starter"
      );
      const { projectName = "" } = customContent;
    
      try {
        await checkName(projectName);
        await downloadTemplate(gitUrl, projectName);
        await changeTemplate(customContent);
    
        console.log(chalk.green("template download completed"));
        console.log(
          chalk.bold.cyan("CosenCli: ") + "a new project starter is created"
        );
      } catch (error) {
        console.log(chalk.red(error));
      }
    }
    
    • 项目校验
    // 创建项目前校验是否已存在
    function checkName(projectName) {
      return new Promise((resolve, reject) => {
        fs.readdir(process.cwd(), (err, data) => {
          if (err) {
            return reject(err);
          }
          if (data.includes(projectName)) {
            return reject(new Error(`${projectName} already exists!`));
          }
          resolve();
        });
      });
    }
    
    • 模板下载
    // 下载仓库模板项目
    function downloadTemplate(gitUrl, projectName) {
      const spinner = ora("download template......").start();
    
      return new Promise((resolve, reject) => {
        download(
          gitUrl,
          path.resolve(process.cwd(), projectName),
          { clone: true },
          function (err) {
            if (err) {
              spinner.fail(); // 下载失败提示
              return reject(err);
            }
            spinner.succeed(); // 下载成功提示
            resolve();
          }
        );
      });
    }
    
    • 多项目切换
    // 多项目切换
    async function changeTemplate(customContent) {
      // name description author
      const { projectName = "", description = "", author = "" } = customContent;
      return new Promise((resolve, reject) => {
        fs.readFile(
          path.resolve(process.cwd(), projectName, "package.json"),
          "utf8",
          (err, data) => {
            if (err) {
              return reject(err);
            }
            let packageContent = JSON.parse(data);
            packageContent.name = projectName;
            packageContent.author = author;
            packageContent.description = description;
            fs.writeFile(
              path.resolve(process.cwd(), projectName, "package.json"),
              JSON.stringify(packageContent, null, 2),
              "utf8",
              (err, data) => {
                if (err) {
                  return reject(err);
                }
                resolve();
              }
            );
          }
        );
      });
    }
    

以上就是主要的一些配置方法,完整的项目配置可以在我的项目仓库里参考。

写到最后

如果以上的配置都做好,那么应该也安装好了自己的 CLI了,以下是我的 CLI 配置参考

cli 搭建.png

搭建完毕.png

文件夹.png

版本号.png

目前有加入Vue的两套模板,一套是 web 端的后台管理系统,一套是 uni-app 的移动端方案,后续的计划是加入 ReactReact Native 的模板,快速搭建项目,解决重复的构建工作。

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 5 天,点击查看活动详情