手把手从零搭建一个 vue3 组件库 (四):使用 vite 打包并发布到 npm

前面几篇文章分享了一个组件库的搭建、组件的编写、样式的处理和编写组件库文档。

今天这篇文章主要来分享一下组件库的打包和发布

话不多说,开搞!!!

在线预览

github 地址

gitee 地址

准备工作

  • 在 packages 目录下创建 vangle 目录,这个目录就是我们要发布的,在这个目录下初始化要发布的 package.json,填写必要的信息
{
  "name": "vangle",
  "version": "1.0.16",
  "description": "A Component Library for Vue 3",
  "keywords": [
    "vangle",
    "component library",
    "ui framework",
    "ui",
    "vue"
  ],
  "homepage": "https://vangleer.github.io/vangle/",
  "bugs": {
    "url": "https://github.com/vangleer/vangle/issues"
  },
  "license": "MIT",
  "main": "dist/index.es.js",
  "module": "dist/index.es.ts",
  "unpkg": "dist/index.umd.js",
  "exports": {
    ".": {
      "import": "./dist/index.es.js",
      "require": "./dist/index.umd.js",
      "types": "./dist/types/vangle/index.d.ts"
    },
    "./*": "./*"
  },
  "repository": {
    "type": "git",
    "url": "https://github.com/vangleer/vangle.git"
  },
  "publishConfig": {
    "access": "public"
  },
  "style": "dist/style.css",
  "scripts": {},
  "author": "vangleer",
  "peerDependencies": {
    "vue": "^3.2.0"
  }
}

  • 新建 index.ts 将 packages/components 目录下的组件全部导出,附加 install 方法注册全部组件
export * from '../components'
import type { App, Plugin } from 'vue'

import { VanButton } from '@vangle/components'

const components = [VanButton] as Plugin[]

const INSTALLED_KEY = Symbol('INSTALLED_KEY')
export const install = (app: App) => {
  if (app[INSTALLED_KEY]) return
  app[INSTALLED_KEY] = true
  components.forEach(comp => app.use(comp))
}

export default {
  install
}

编写打包脚本

步骤:

  • 根目录新建 scripts/build.js
const path = require('path')
const fs = require('fs')

// 使用vite打包
const { build, defineConfig } = require('vite')

// 用到的插件
const vue = require('@vitejs/plugin-vue')
const dts = require('vite-plugin-dts')
const DefineOptions = require('unplugin-vue-define-options/vite')

// 根目录
const rootDir = path.resolve(__dirname, '../')

// 打包后的目录
const outDir = resolve('packages/vangle/dist')

const baseConfig = defineConfig({
  plugins: [
    vue(),
    DefineOptions(),
    dts({
      include: ['packages/vangle', 'packages/components'],
      outputDir: path.resolve(outDir, 'types')
    })
  ],
  build: {
    lib: {
      entry: resolve('packages/vangle/index.ts'),
      name: 'vangle',
      fileName: format => `index.${format}.js`
    },
    outDir,
    rollupOptions: {
      // 确保外部化处理那些你不想打包进库的依赖
      external: ['vue'],
      output: {
        // 在 UMD 构建模式下为这些外部化的依赖提供一个全局变量
        globals: {
          vue: 'Vue'
        }
      }
    }
  }
})

main()

async function main() {
  // build
  await build(baseConfig)

  await copyFiles()
}

async function copyFiles() {
  // fs.copyFileSync(
  //   resolve('packages/vangle/package.json'),
  //   resolve('packages/vangle/dist/package.json')
  // )
  fs.copyFileSync(
    resolve('README.md'),
    resolve('packages/vangle/README.md')
  )
}

function resolve(...urlOrUrls) {
  return path.resolve(rootDir, ...urlOrUrls)
}

  • 在 package.json 中添加打包脚本
{
  "scripts": {
    "build": "node ./scripts/build.js"
  }
}

发布到 npm 上

步骤:

  1. 如果没有传入版本,提示可选版本
  2. 根据所选版本,更新所有包 package.json 的版本号
  3. git 提交并打上 tag
  4. npm 发布,没有登录的话会提示先登录
  • 根目录新建 scripts/release.js
const { execSync } = require('child_process')
const chalk = require('chalk')
const path = require('path')
const fs = require('fs')

const semver = require('semver')
const { prompt } = require('enquirer')
const args = require('minimist')(process.argv.slice(2))
const currentVersion = require('../package.json').version

const packages = ['vangle', 'components']

const versionIncrements = ['patch', 'minor', 'major']
const step = msg => console.log(chalk.cyan(msg))
const getPkgRoot = pkg => path.resolve(__dirname, '../packages/' + pkg)

const inc = i => semver.inc(currentVersion, i)

async function main() {
  let targetVersion = args._[0]

  // 如果没有传入版本,提示选择
  if (!targetVersion) {
    // no explicit version, offer suggestions
    const { release } = await prompt({
      type: 'select',
      name: 'release',
      message: 'Select release type',
      choices: versionIncrements.map(i => `${i} (${inc(i)})`).concat(['custom'])
    })

    if (release === 'custom') {
      targetVersion = (
        await prompt({
          type: 'input',
          name: 'version',
          message: 'Input custom version',
          initial: currentVersion
        })
      ).version
    } else {
      targetVersion = release.match(/\((.*)\)/)[1]
    }
  }

  if (!semver.valid(targetVersion)) {
    throw new Error(`invalid target version: ${targetVersion}`)
  }

  const { yes } = await prompt({
    type: 'confirm',
    name: 'yes',
    message: `Releasing v${targetVersion}. Confirm?`
  })

  if (!yes) {
    return
  }

  // update all package versions and inter-dependencies
  step('\nUpdating cross dependencies...')
  updateVersions(targetVersion)

  // publish packages
  step('\nPublishing packages...')

  for (const pkg of packages) {
    await publishPackage(pkg, targetVersion)
  }
}

main()

function updateVersions(version) {
  // 1. update root package.json
  updatePackage(path.resolve(__dirname, '..'), version)
  // 2. update all packages
  packages.forEach(p => updatePackage(getPkgRoot(p), version))
}

function updatePackage(pkgRoot, version) {
  const pkgPath = path.resolve(pkgRoot, 'package.json')
  const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'))
  pkg.version = version
  fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + '\n')
}

async function publishPackage(pkgName, version) {
  const pkgRoot = getPkgRoot(pkgName)
  const pkgPath = path.resolve(pkgRoot, 'package.json')
  const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'))
  if (pkg.private) {
    return
  }

  step(`Publishing ${pkgName}...`)
  console.log(pkgRoot, 'pkgRootpkgRoot')

  try {

    execSync('git add .', { stdio: 'inherit' })

    execSync(`git commit -m "chore: release v${version}"`, { stdio: 'inherit' })
    execSync(`git tag -a v${version} -m "v${version}"`, { stdio: 'inherit' })
    execSync('npm publish', { cwd: pkgRoot, stdio: 'inherit' })
    
    console.log(chalk.green(`Successfully published ${pkgName}@${version}`))
  } catch (e) {
    if (e.stderr.match(/previously published/)) {
      console.log(chalk.red(`Skipping already published: ${pkgName}`))
    } else {
      throw e
    }
  }
}

  • 在 package.json 中添加发布脚本
{
  "scripts": {
    "release": "node ./scripts/release.js"
  }
}
  • 3
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
Vue是一种用于构建用户界面的渐进式JavaScript框架,它可以通过封装组件来实现可复用、模块化以及易于维护的代码。下面我将介绍如何对Vue组件进行封装,并将其打包发布npm上供他人使用。 首先,我们需要创建一个Vue项目,并在项目中使用Vue CLI来进行组件的开发和构建。可以通过以下命令创建一个新的Vue项目: ``` vue create my-component ``` 接下来,您可以通过Vue CLI支持的任何方式(如单文件组件JavaScript脚本等)创建自定义组件。在组件的开发过程中,可以利用Vue提供的各种功能和特性,比如计算属性、生命周期钩子函数、模板语法等。确保你的组件功能完备、可复用且易于理解。 完成组件的开发后,我们需要将其打包成可用的npm包。Vue CLI可以帮助我们自动进行打包,只需执行以下命令: ``` npm run build ``` 该命令将生成一个dist文件夹,其中包含了打包后的组件代码。 接下来,我们需要在项目的根目录中创建一个package.json文件,用于描述我们的npm包,并设置一些配置信息。其中,name字段用于定义npm包的名称,version字段用于定义npm包的版本号。其他字段根据您的需要进行设置。然后,执行以下命令将package.json文件拷贝到dist文件夹中: ``` cp package.json dist/ ``` 然后,我们需要登录到npm官方网站,并创建一个账户。接着,使用以下命令进行登录: ``` npm login ``` 在登录成功后,使用以下命令发布npm包: ``` npm publish dist/ ``` 完成上述步骤后,您的自定义Vue组件就已经发布到了npm上。其他开发者可以通过以下命令安装并使用您的组件: ``` npm install your-component ``` 然后,在他们的Vue项目中,可以通过import语句引入您的组件,并在模板中使用它。 至此,我们已经学习了如何封装自定义Vue组件,并通过npm发布,供他人使用。希望这能帮助到您!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值