资讯专栏INFORMATION COLUMN

通过npm或yarn自动生成vue组件

masturbator / 2200人阅读

摘要:不知道大家每次新建组件的时候,是不是都要创建一个目录,然后新增一个文件,然后写这些东西,如果是公共组件,是不是还要新建一个用来导出组件虽然有有代码片段能实现自动补全,但还是很麻烦,今天灵活运用工作流,自动生成文件和目录。

不知道大家每次新建组件的时候,是不是都要创建一个目录,然后新增一个.vue文件,然后写template、script、style这些东西,如果是公共组件,是不是还要新建一个index.js用来导出vue组件、虽然有vscode有代码片段能实现自动补全,但还是很麻烦,今天灵活运用scripts工作流,自动生成vue文件和目录。

实践步骤

安装一下chalk,这个插件能让我们的控制台输出语句有各种颜色区分
npm install chalk --save-dev
yarn add chalk --save-dev

在根目录中创建一个 scripts 文件夹

新增一个generateComponent.js文件,放置生成组件的代码

新增一个template.js文件,放置组件模板的代码

template.js文件,里面的内容可以自己自定义,符合当前项目的模板即可

// template.js
module.exports = {
  vueTemplate: compoenntName => {
    return `





`
  },
  entryTemplate: `import Main from "./main.vue"
export default Main`
}

generateComponent.js生成vue目录和文件的代码

// generateComponent.js`
const chalk = require("chalk") // 控制台打印彩色
const path = require("path")
const fs = require("fs")
const resolve = (...file) => path.resolve(__dirname, ...file)
const log = message => console.log(chalk.green(`${message}`))
const successLog = message => console.log(chalk.blue(`${message}`))
const errorLog = error => console.log(chalk.red(`${error}`))
const { vueTemplate, entryTemplate } = require("./template")
const _ = process.argv.splice(2)[0] === "-com"

const generateFile = (path, data) => {
  if (fs.existsSync(path)) {
    errorLog(`${path}文件已存在`)
    return
  }
  return new Promise((resolve, reject) => {
    fs.writeFile(path, data, "utf8", err => {
      if (err) {
        errorLog(err.message)
        reject(err)
      } else {
        resolve(true)
      }
    })
  })
}

// 公共组件目录src/base,全局注册组件目录src/base/global,页面组件目录src/components
_ ? log("请输入要生成的组件名称、如需生成全局组件,请加 global/ 前缀") : log("请输入要生成的页面组件名称、会生成在 components/目录下")
let componentName = ""
process.stdin.on("data", async chunk => {
  const inputName = String(chunk).trim().toString()

  // 根据不同类型组件分别处理
  if (_) {
    // 组件目录路径
    const componentDirectory = resolve("../src/base", inputName)
    // vue组件路径
    const componentVueName = resolve(componentDirectory, "main.vue")
    // 入口文件路径
    const entryComponentName = resolve(componentDirectory, "index.js")

    const hasComponentDirectory = fs.existsSync(componentDirectory)
    if (hasComponentDirectory) {
      errorLog(`${inputName}组件目录已存在,请重新输入`)
      return
    } else {
      log(`正在生成 component 目录 ${componentDirectory}`)
      await dotExistDirectoryCreate(componentDirectory)
    }

    try {
      if (inputName.includes("/")) {
        const inputArr = inputName.split("/")
        componentName = inputArr[inputArr.length - 1]
      } else {
        componentName = inputName
      }
      log(`正在生成 vue 文件 ${componentVueName}`)
      await generateFile(componentVueName, vueTemplate(componentName))
      log(`正在生成 entry 文件 ${entryComponentName}`)
      await generateFile(entryComponentName, entryTemplate)
      successLog("生成成功")
    } catch (e) {
      errorLog(e.message)
    }
  } else {
    const inputArr = inputName.split("/")
    const directory = inputArr[0]
    let componentName = inputArr[inputArr.length - 1]

    // 页面组件目录
    const componentDirectory = resolve("../src/components", directory)

    // vue组件
    const componentVueName = resolve(componentDirectory, `${componentName}.vue`)

    const hasComponentDirectory = fs.existsSync(componentDirectory)
    if (hasComponentDirectory) {
      log(`${componentDirectory}组件目录已存在,直接生成vue文件`)
    } else {
      log(`正在生成 component 目录 ${componentDirectory}`)
      await dotExistDirectoryCreate(componentDirectory)
    }

    try {
      log(`正在生成 vue 文件 ${componentName}`)
      await generateFile(componentVueName, vueTemplate(componentName))
      successLog("生成成功")
    } catch (e) {
      errorLog(e.message)
    }
  }

  process.stdin.emit("end")
})

process.stdin.on("end", () => {
  log("exit")
  process.exit()
})

function dotExistDirectoryCreate (directory) {
  return new Promise((resolve) => {
    mkdirs(directory, function () {
      resolve(true)
    })
  })
}

// 递归创建目录
function mkdirs (directory, callback) {
  var exists = fs.existsSync(directory)
  if (exists) {
    callback()
  } else {
    mkdirs(path.dirname(directory), function () {
      fs.mkdirSync(directory)
      callback()
    })
  }
}

配置package.json,scripts新增两行命令,其中-com是为了区别是创建页面组件还是公共组件

"scripts": {
    "new:view":"node scripts/generateComponent",
    "new:com": "node scripts/generateComponent -com"
  },

执行

    npm run new:view // 生成页组件
    npm run new:com // 生成基础组件
    或者
    yarn run new:view // 生成页组件
    yarn run new:com // 生成基础组件

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/101598.html

相关文章

  • vue-cli3 搭建的前端项目基础模板

    摘要:基于搭建的前端模板,本仓库,即可搭建完成一个新项目的基础模板,源码地址,欢迎或特性预编译语言,做了一定的封装,详见雪碧图移动的适配方案引入了及,可以自由地用去开发常用的工具类引用全局注入相关的文件,如通用的及等常用的的集合支持 基于 vue-cli3 搭建的前端模板,clone 本仓库,即可搭建完成一个新项目的基础模板,源码地址,欢迎 star 或 fork 特性 CSS 预编译语言...

    william 评论0 收藏0
  • Vue现有项目改造为Nuxt项目

    摘要:好了,项目启动了,目录结构也清楚了,接下来就是整个现有项目的迁移了目前正在改造项目,文章尚未写完,会抽时间不定期的继续更新项目的改造过程及分享改造过程中遇到的问题 公司项目,最初只为了实现前后端分离式开发,直接选择了vue框架进行开发,然而现在项目基本完成了,发现蜘蛛根本就抓取不到网站数据,搜索引擎搜出来,都是一片空白没有数据,需要对项目做SEO优化。 本人第一次接触SEO的优化,完全...

    Invoker 评论0 收藏0
  • Vue-Donut——专用于构建Vue的UI组件库的开发框架

    摘要:相信不少使用的开发者和公司都有定制一套属于自己的组件库的需求。针对这个问题,我搭建了一个专门用来构建的组件库的开发框架,以节省搭建环境的劳动力,专心于组件库的开发。首先我们尝试了使用的方案,就是把组件库直接作为项目的子模块使用。 showImg(https://segmentfault.com/img/bVNais?w=1226&h=1159); 相信不少使用Vue的开发者和公司都有定...

    stormgens 评论0 收藏0
  • ElementUI的构建流程

    摘要:下面一步步拆解上述流程。切换至分支检测本地和暂存区是否还有未提交的文件检测本地分支是否有误检测本地分支是否落后远程分支发布发布检测到在分支上没有冲突后,立即执行。 背景 最近一直在着手做一个与业务强相关的组件库,一直在思考要从哪里下手,怎么来设计这个组件库,因为业务上一直在使用ElementUI(以下简称Element),于是想参考了一下Element组件库的设计,看看Element构...

    wudengzan 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<