前端公共组件库发布:公共组件库如何在其他项目中使用?(Vue 项目为例)

事先声明:

下文中可能涉及到的 nvm node 管理工具、nrm 镜像管理工具本篇不提及它们的安装与如何使用,具体的可以参考这篇Node 安装教程:不同平台安装配置 Node.js & 使用 nvm 管理多版本 Node 与无缝切换(Windows)以及 nrm 镜像管理工具

当我们不论是个人开发项目还是在公司中进行代码开发时,聪明的程序员们总会在日积月累中发现各个项目之间的共性,并能提取抽离且搭建出自己或项目组内可以使用的前端公共组件库,那么我该如何搭建组件库并能够在其他项目中使用呢???

话不多说,下面将会介绍几种常见的前端公共组件库的发布/使用方式:

  1. 手动下载和引入:适用于 组件库较小且不经常更新 的情况。

  2. 本地或内网服务器:适用于 内网环境 中使用。

  3. npm link:适用于组件库和项目都在本地开发环境下,在本地开发阶段测试组件库 的情况。

  4. ❤️Git 仓库发布:适用于组件库代码托管在 Git 开源仓库 或 Git 仓库内网私服(内网私有化开发) 。

  5. ❤️npm 发布到包管理工具:适用于 组件库已经稳定并且可以被其他项目广泛使用

  6. 使用 CDN:适用于 已经发布到 CDN 的组件库。

1. 手动下载和引入(手动复制)

如果你的组件库比较小且不经常更新,最简单的办法就是你可以手动将组件库文件复制粘贴到其他项目中,并在其他项目中引用。

这种手动复制组件库文件的方式,在我个人理解来看,本质上和你在该需要使用组件库项目内书写的 Component 组件并无差别,只是省去了书写代码的这个过程,改为直接拷贝别人的代码(也可能是自己的代码)到项目中变成自己项目的一部分。

与组件库的依赖关系:这种方式直接依赖于复制的文件,与组件库的实际位置无关。

更新机制:组件库更新时,需要手动将新版本的文件复制到其他项目,其他项目才能获取到更新。

步骤

  1. 将组件库文件手动复制到其他项目:将组件库的构建文件手动复制到其他项目的相应目录。

  2. 在其他项目中导入和使用:

// 手动引入的组件库使用:在你的Vue组件中 绝对路径
import YourComponent from '@/path/to/your-component-library/YourComponent.vue';
export default {
  components: {
    YourComponent
  },
  // ...其他组件配置
};

2. 本地或内网服务器

如果你的组件库是在内网环境中使用 ,你可以将组件库文件托管在本地或内部服务器上,并在其他项目中引用。

更新机制:组件库更新时,需要手动将新版本的构建文件复制到本地或内部服务器,其他项目才能获取到更新。

注意事项:

  1. 跨域问题: 在使用网络路径时,可能会涉及到跨域问题,需要确保服务器允许跨域请求或配置相关代理。

  2. 版本控制: 如果需要更好的版本控制和更新机制,考虑使用 Git 仓库内网私服或其他版本控制工具。

  3. 开发阶段方便性: 在开发阶段,可以通过配置本地开发服务器的代理来方便地调试和使用组件库。

步骤

  1. 将组件库文件托管在本地或内部服务器:将组件库的构建文件放置在可被其他项目访问的地方,可以是本地服务器内部服务器的某个路径或者专门的组件库服务器等

  2. 在其他项目中引用:在项目中使用相对路径或 URL 引用组件库:

/**************************************************************************************
 * 方式一:本地服务器路径 - 组件库文件托管在本地服务器上,可以通过本地服务器路径进行引用
 **************************************************************************************/
// 在其他项目的Vue组件中
import YourComponent from 'http://localhost:port/path/to/your-component-library/YourComponent.vue';
export default {
  components: {
    YourComponent
  },
  // ...其他组件配置
};
/**************************************************************************************
 * 方式二:内部服务器路径 - 组件库文件托管在内部服务器上,可以通过内部服务器路径进行引用
 **************************************************************************************/
// 在其他项目的Vue组件中
import YourComponent from 'http://internal-server:port/path/to/your-component-library/YourComponent.vue';
……

这种方式适用于组件库和项目都在本地开发环境下,本地开发阶段测试组件库 ,而不用频繁发布和更新。

npm link 是 npm 提供的一个功能,允许你在本地开发时将一个正在开发中的包(比如你的 Vue 组件库)链接到另一个正在开发的项目中。主要目的是在本地测试你的包,而无需每次更改后都重新发布。

更新机制:当你在组件库中做了修改后,你只需重新构建或重新打包组件库,其他项目就会自动获取到更新。

步骤:

⒈组件库项目创建链接:在组件库项目根目录中执行 npm link这个命令会在全局 node_modules 目录中创建一个符号链接,使得该组件库可以在其他项目中使用

⒉其他项目引入组件库:在其他项目根目录中执行 npm link your-component-library这样就会在当前项目的 node_modules 目录下创建一个指向你的组件库的符号链接

⒊Vue 项目中使用: 在其他项目中可以通过正常的导入语句引入和使用组件。

⒋取消链接如果需要取消链接,可以分别在组件库项目和其他项目中执行以下命令:组件库项目npm unlink;其他项目 npm unlink your-component-library

// 项目中使用
import { YourComponent } from 'your-component-library';
export default {
  components: {
    YourComponent
  },
  // ...其他组件配置
};

4. Git 仓库发布

如果你的组件库代码托管在 Git 开源仓库 或 Git 仓库内网私服 中 ,都需要设置组件库仓库可见性为公开 Public,然后其他项目可以通过 Git 地址的方式安装和使用。

此处的 Git 仓库可以是GitHubGitee 码云GitLabGitea 等,根据自己需求选择。

  • Git 开源仓库:由于开源,所有人都可见都能下载,存在代码泄露风险。

  • Git 仓库内网私服:个人或项目组在内网搭建的 Git 仓库私服,可控制成员可见性,更安全。

更新机制

  • 引入组件库: 使用者通过引入 GitHub Release 或者 Git Tag 中的特定版本来使用组件库。

  • 更新组件库: 使用者需要手动查看组件库已发布的 Release 或者 Git Tag,并在项目中更新到特定版本。

步骤注意确保组件库所在的 Git 仓库代码可见性设置为公开

步骤1:在其他项目中安装/引入依赖:安装后在 node_modules 中就会有这个依赖包。

方式一直接 npm install 安装组件库项目依赖。

npm install git+https://github.com/your-username/your-component-library.git  # 示例

方式二或在 package.json 中引入依赖,然后 执行npm install命令 安装。

"common-component": "git+https://github.com/your-username/your-component-library.g

步骤2:在项目中使用:

import { YourComponent } from 'your-component-library';
export default {
  components: {
    YourComponent
  },
  // ...其他组件配置
};

npm 安装 Git 仓库的协议

详情请参考:Git URLs as Dependencies__package.json | npm Docs

我们可以使用 Git URL 来标识依赖项, 本质上是 install 一个 URL,npm 安装 Git 仓库:npm install <git remote url>

一些使用 Git URL 作为依赖项的例子:

git+ssh://git@github.com:npm/cli.git#v1.0.27
git+ssh://git@github.com:npm/cli#semver:^5.0
git+https://isaacs@github.com/npm/cli.git
git://github.com/npm/cli.git#v1.0.27

Git urls are of the form:协议格式如下

<protocol>://[<user>[:<password>]@]<hostname>[:<port>][:][/]<path>[#<commit-ish> | #semver:<semver>]

协议说明:

-------------------------------------------------------------------------------------------------
<protocol>://[<user>[:<password>]@]<hostname>[:<port>][:][/]<path>[#<commit-ish> | #semver:<semver>]
-------------------------------------------------------------------------------------------------
<protocol> - 协议:可以是 git, git+ssh, git+http, git+https, or git+file
#<commit-ish>:
如果 #<commit-ish> 提供,它将用于克隆该提交。
#semver:<semver>:
如果提交的格式 #semver:<semver> 为 ,可以是任何有效的 semver 范围或确切版本,npm 将在远程存储库中查找与该范围匹配的任何标签或引用, <semver> 就像注册表依赖项一样。
如果两者都未 #<commit-ish> 指定 OR #semver:<semver> ,则使用默认分支。
通常在实际开发使用时,是这么写的:(reposity - xxx.git)
npm install git+https://username:password@github.com/path/reposity#1.0.0
npm install git+https://github.com/username/reposity#1.0.0

5. npm 发包:npm 发布到包管理工具

通常情况下,采用 npm 或 Yarn 发布到包管理工具,这是最常见的方式,适用于组件库已经稳定并且可以被其他项目广泛使用

更新机制

  • 引入组件库: 使用者将你的组件库发布到 npm 或者私有 npm 仓库,并通过 npm installyarn add 引入到项目中。

  • 更新组件库: 使用者可以通过运行 npm update your-packageyarn upgrade your-package 来更新组件库到最新版本。

npm(Node Package Manager)是 JavaScript 生态系统中用于包管理的工具,允许开发者发布和使用 JavaScript 模块。npm 支持公有包和私有包两种类型。

5.1. npm 公有包

参考来源:感谢分享~

vue封装公共组件库并发布到npm库 - Stitchhhhh - 博客园

一些npm发包后,图片资源路径可能导致发生的错误问题(建议 将图片上传到服务器或者cdn服务端在组件库中引用 这种办法较好)

公有包是指通过 npm 仓库公开发布的包,任何人都可以通过 npm install 命令来安装和使用这些包。这些包的源代码和版本信息是公开可见的。大多数开源项目和常用的 JavaScript 库都是以公有包形式发布。

特点和优势:

  • 易于分享和发现: 公有包使得开发者能够轻松地分享自己的代码,并让其他开发者发现和使用它们。

  • 免费使用: 大多数公有包是免费的,可以直接通过 npm 下载并使用,无需额外费用。

  • 社区贡献: 公有包通常是开源的,因此任何人都可以贡献代码、报告问题或提出改进建议。

5.1.1. 组件库项目准备

步骤一:初始化项目

使用 Vue CLI 或其他方式创建一个新的 Vue 项目(Vue2 或 Vue3 )。

选择 "Manually select features" 以手动选择特性,可以选择 Babel、Router、Vuex、CSS Pre-processors、Linter / Formatter,并使用默认配置。

vue create vue-component-library		# 项目名称自定义即可

步骤二:创建组件

以简单的 Button 组件为例,在 src/components 目录下创建一个名为 Button.vue 的组件文件。

需要注意的是,组件必须声明 name,这个 name 就是组件的标签。

<template>
  <button class="my-button">
    <slot></slot>
  </button>
</template>
<script>
  export default {
    name: 'MyButton'
  };
</script>
<style scoped>
  .my-button {
    /* 样式可以根据实际需要进行定制 */
    padding: 10px 20px;
    font-size: 16px;
    background-color: #4caf50;
    color: #fff;
    border: none;
    border-radius: 5px;
    cursor: pointer;
  }
</style>

步骤三:(可选)测试组件效果 =》注册组件 & 使用组件

此步骤非必需,主要是为了查看自己的组件库项目中编写的组件实际展示效果,便于后期调整。

src/main.js 中注册你的组件 → 在 src/App.vue 中使用你的按钮组件 → npm run serve启动项目查看效果,确保组件能够正常显示。

Vue2:src/main.js 注册组件

import Vue from 'vue';
import App from './App.vue';
import MyButton from './components/Button.vue';  
Vue.component('MyButton', MyButton);  
new Vue({
  render: h => h(App),
}).$mount('#app');

Vue3:src/main.js 注册组件

import { createApp } from 'vue';
import App from './App.vue';
import MyButton from './components/Button.vue';
const app = createApp(App);
app.component('MyButton', MyButton);
app.mount('#app');

src/App.vue 中使用组件:

<template>
  <div id="app">
   	<my-button>Hello World!</my-button>
  </div>
</template>
<script>
</script>
<style>
  /* 在这里可以添加全局样式 */
</style>

运行项目查看效果:

npm run serve

步骤四:配置打包入口

src/components 目录下,创建一个index.js 文件,用于配置打包入口:

import MyButton from "./Button.vue"; // 导入租金
// 组件列表
const components = [MyButton];
// 定义install方法,接收Vue作为参数,可以在Vue的原型上注册组件
const install = function (Vue) {
  components.forEach((component) => {
    Vue.component(component.name, component);
  });
};
// 判断是否是直接引入文件(通过script导入),如果是,就不用调用Vue.use()
if (typeof window !== "undefined" && window.Vue) {
  install(window.Vue);
}
// 导出install方法,以便在Vue.use()时调用
export default {
  install,
};

步骤五:配置打包命令、npm 入口、版本号 等信息

此步骤很重要,关系着后续 npm 包的正确发布,在 package.json 文件中配置如下信息:关于package.json详细配置信息参考文

如果计划发布包,package.json 中最重要的内容是 name 和 version 字段,因为它们是必需的。名称和版本共同构成一个标识符,该标识符假定是完全唯一的。如果不打算发布包,则 “名称” 和 “版本” 字段是可选的。

  • name:包名,该名字是唯一的。设置时可在 npm 官网 搜索名字,若存在就换个名字。

  • version:版本号,不能和历史版本号相同。

  • description描述信息。这是一个字符串,它在 npm search 中列出。

  • keywords:关键词,便于搜索。它是一个字符串数组,它在 npm search 中列出。

  • homepage:网站首页,项目主页的 URL。可以设置为组件文档或 demo 示例。

  • mainmain 字段是程序的主要入口点。

  • private:设置为 false, 如果你在 package.json 中设置 "private": true ,那么 npm 将拒绝发布它。

  • repository:仓库地址,指定代码所在的位置。这对想要做出贡献的人很有帮助。


package.json 中添加 lib 脚本用于配置打包命令:

vue-cli-service build 命令是 Vue CLI 提供的一个用于构建项目的命令,vue-cli-service build --target lib 参考

打包命令:添加脚本用于配置打包命令:

"scripts": {
  "lib": "vue-cli-service build --target lib --name my-vue2-library --dest lib src/components/index.js"
}

vue-cli-service build --target lib --name myLib [entry]:

# 此命令命令将一个单独的入口构建为一个库  
# 这个入口可以是一个 .js 或一个 .vue 文件。如果没有指定入口,则会使用 src/App.vue。
vue-cli-service build --target lib --name myLib --dest lib [entry]  
  • --target lib:指定了构建的目标是一个库(Library)。当指定为 lib 时,Vue CLI 会生成一个可以通过 script 标签引入的 JavaScript 库。这通常用于创建可在不同项目中重用的 Vue.js 组件库。

  • --name myLib: 这个选项指定了生成的库的名称。在这里,库的名称被设置为 myLib。当你在其他项目中引入这个库时,可以通过这个名称来访问其中的组件或功能。

  • --dest lib: 这个选项指定了输出目录,即构建完成后生成的文件将放置在 lib 目录中。这允许你自定义输出目录,而不是默认的 dist。

  • [entry]: 这是构建的入口文件。它表示你的项目的主要文件或者入口文件,其中包含了整个项目的逻辑。这个入口文件的路径会被提供,例如 src/main.js。在这里,你会把整个项目的代码捆绑在一起,然后构建工具会生成相应的输出文件。

# 构建一个库会输出:
# dist/myLib.common.js:一个给打包器用的 CommonJS 包 (不幸的是,webpack 目前还并没有支持 ES modules 输出格式的包)
# dist/myLib.umd.js:一个直接给浏览器或 AMD loader 使用的 UMD 包
# dist/myLib.umd.min.js:压缩后的 UMD 构建版本
# dist/myLib.css:提取出来的 CSS 文件 (可以通过在 vue.config.js 中设置 css: { extract: false } 强制内联)
vue-cli-service build --target lib --name myLib src/main.js
# 使用 Vue CLI 构建一个名为 "myLib" 的 JavaScript 库,入口文件为 src/main.js。
# 构建输出通常会包括一个 UMD 模块,你可以在浏览器或其他环境中引入该模块,也可以通过 CommonJS 或 ES 模块的方式在 Node.js 或其他支持这些模块的环境中使用。

package.json确保 main字段指向打包后的入口文件:

"main": "lib/my-vue2-library.umd.min.js",
"version": "1.0.0",
"private": false,

步骤六:打包

执行打包命令npm run lib打包成功后会得到一个名为 lib 的文件夹,lib 目录下会生成一个 my-vue2-library.umd.min.js 文件。

至此,一个简单的 Vue 前端公共组件库项目就已经完成啦~ 接下来我们要做的就是 npm 发包操作。

5.1.2. 发布 npm 公有包(npm login + npm publish)

(可选项)可以在项目的根目录下增加一个.npmignore 文件,设置将一些不需要上传到 npm 的路径、文件进行忽略。

.npmignore文件:

# 忽略非必要上传到npm的目录与指定文件,这里只将lib打包文件夹与package.json上传
/node_modules
/public
/src
.browserslistrc
.eslintrc.js
.gitignore
babel.config.js
vue.config.js
# Editor directories and files
.idea

步骤一:注册 npm 账号 如果你还没有 npm 账号,首先需要在 npm 官网 上注册一个账号。注意首次注册登录后务必请开启 2FA 验证功能,否则后续登录或发包时可能会失败!

步骤二:检查 npm 源:在登录 npm 账号之前,务必确保 npm 源为官方源。

# 方式一:使用 nrm 镜像管理工具 检查源
nrm ls   			# 查看镜像列表,带星号的为当前使用源
nrm use npm   # 切换源
nrm current		# 检查当前源
# 方式二:使用 npm 命令 检查源,官方源为 https://registry.npmjs.org/
npm config get registry    										# 查看当前源,不是则要切换
npm config set registry https://registry.npmjs.org/			# 切换为官方源

步骤三:登录 npm 账号:在项目终端中运行npm login命令,输入你在 npm 官网注册时使用的用户名、密码和邮箱。

npm login  # 或者  yarn login

步骤四:发布到 npm:运行npm publish命令发布你的组件库到 npm。

发布成功后,在 npm 官网 登录后查看发布的库。

请注意,若再次上传到 npm ,需要修改 package.json 中的版本号 version

此外 上传的 npm 包,在 72 小时 后不可删除,如果是测试用的包,记得 72 小时 内删除。

# 使用 npm 发布
npm publish
# 或者使用 yarn 发布
yarn publish

5.1.3. 使用 npm 公有包

在另一个 Vue 项目中使用:

步骤 一:安装公有包,使用 npm install 命令安装已发布的前端组件库(已发布成功的 npm 包),注意包名为自己 npm 发包时设置的包名(package.json 中的 name 字段)。

npm install my-vue2-library
# 或者
yarn add my-vue2-library

步骤二:在项目中使用前端组件库中的组件。

// main.js 全局引入
import Vue from 'vue'
import App from './App.vue'
import MyComponentUI from 'my-vue2-library'
import 'my-vue2-library/lib/my-vue2-library.css'  // 一定要引入样式文件,否则可能样式不生效
Vue.use(MyComponentUI)
<!--vue 组件中使用-->
<template>
  <div>
   	<my-button>Hello World!!!</my-button>
  </div>
</template>

5.2. npm 私有包

私有包是指只能被特定用户或组织访问和使用的包。这些包通常包含敏感信息或专有功能,不适合公开分享。npm 提供了一种方式来创建和管理私有包。

特点和优势:

  • 安全和保密: 私有包中的代码和信息只有被授权的用户才能访问,适用于一些商业项目或包含敏感信息的代码。

  • 定制功能: 私有包允许团队内部分享和使用特定于项目或组织需求的功能模块,而不必将其公开。

  • 灵活性: 私有包的发布和使用可以按照团队或组织的需要进行管理,无需公开和维护。

npm 私有包发布(以下仅介绍和 npm 公有包的不同之处,其它更多的设置信息参考 npm 公有包

  • 配置私有包相关信息: 在项目的 package.json 文件中配置私有包的访问信息,添加 "private": true,以标识这是一个私有包;并使用 npm install 安装,例如:

"dependencies": {
  "private-package": "registry-url/private-package"
}
  • 发布私有包: 使用 npm publish --access restricted 命令将私有包发布到 npm 仓库,其中 --access restricted 表示这是一个私有包。

  • 身份验证: 对于私有包的发布和安装,可能需要进行身份验证,可以使用 npm login 登录以提供访问权限。

6. 使用 CDN

将前端组件库发布到 CDN上可以使其在全球范围内更快地加载,如果组件库已经发布到 CDN,你可以通过在 HTML 文件中添加 script 标签来引入。

6.1. 组件库发布到 CDN

⒈构建你的组件库项目: 确保你的组件库项目可以被打包成可在浏览器中运行的文件。通常,这包括将你的 Vue 组件编译为 JavaScript 文件。

⒉打包组件库:npm run build,使用工具(例如 Webpack、Rollup 等)将你的组件库打包成一个或多个文件,这些文件可以在浏览器中运行。确保生成的文件包含所有必需的依赖关系。

⒊选择一个 CDN 提供商: 选择一个 CDN 提供商,比如 Cloudflare, Akamai, 或者使用一些免费的提供商如 Netlify, Vercel 等。

⒋上传资源到 CDN: 将构建后的前端资源上传到 CDN。不同的 CDN 提供商可能有不同的上传方式,但通常你可以使用 FTP、SFTP、或者通过提供商的 Web 界面上传。

注册并配置 CDN: 注册一个 CDN 账户,并根据提供商的文档配置你的 CDN 服务。这通常包括创建一个新的 CDN 到你的项目,并配置域名、SSL、缓存策略等。 以 Netlify 为例

创建 Netlify 账户: 如果你还没有 Netlify 账户,可以在官方网站上注册并创建一个账户。

新建一个 Netlify 项目: 在 Netlify 控制台中,点击 "New Site from Git" 按钮,并选择你的组件库所在的 Git 仓库。设置构建命令和发布目录。

  • ⅰ构建命令:根据你的项目需要,通常是运行构建脚本的命令,比如 npm run build

  • ⅱ发布目录:设置为你的组件库构建后的输出目录。

部署到 Netlify: Netlify 会自动监听你的仓库,并在每次代码推送时触发构建和部署过程。一旦构建成功,你的组件库将被部署到 Netlify CDN。

⒌获取 CDN URL: 一旦上传完成,你将获得一个 CDN 路径,类似于:https://cdn.jsdelivr.net/gh/your-username/your-repo@version/

  • 如在 Netlify 控制台中,找到你的项目,并在 "Deploys" 选项卡中找到最新的部署。在 "Deploys" 选项卡底部,你将找到一个部署 URL,这就是你的组件库在 CDN 上的地址。

6.2. 在其他项目中使用 CDN 上的组件库

⒈引入 CDN 资源: 在你的项目中,使用 <script> 标签引入你的组件库。将 CDN URL 替换为你在 Netlify 或其他 CDN 提供商上获得的 URL。

<!-- 引入样式 -->
<link rel="stylesheet" href="https://your-cdn-url/path/to/cdn/your-component-library.css">
<!-- 引入脚本 -->
<script src="https://your-cdn-url/path/to/cdn/your-component-library.js"></script>
<!-- 版本管理: 如果你的组件库有版本概念,确保在引用时指定特定版本号 -->
<!-- 引入特定版本的样式和脚本 -->
<link rel="stylesheet" href="https://your-cdn-url/path/to/cdn/your-component-library-v1.2.3.css">
<script src="https://your-cdn-url/path/to/cdn/your-component-library-v1.2.3.js"></script>

⒉在项目中使用组件: 一旦组件库被引入,你就可以在项目中使用组件,就像在本地开发时一样。

<template>
  <div>
    <!-- 在你的项目中使用 CDN 引入的组件 -->
    <YourComponent />
  </div>
</template>
<script>
// 在你的 Vue 组件中
import YourComponent from 'https://cdn.jsdelivr.net/gh/your-username/your-repo@version/your-component.vue';
export default {
  components: {
    YourComponent
  },
  // ...其他组件配置
};
</script>

⒊样式和依赖关系: 确保你的组件库在 CDN 上发布时,所有的样式和依赖关系也都被正确地包含在发布的文件中。这通常需要在构建过程中正确地配置。

⒋版本控制/版本管理: 如果可能,将组件库的版本号包含在 CDN URL 中,以确保你可以在需要时轻松切换到其他版本。

<!-- 版本管理: 如果你的组件库有版本概念,确保在引用时指定特定版本号 -->
<!-- 引入特定版本的样式和脚本 -->
<link rel="stylesheet" href="https://your-cdn-url/path/to/cdn/your-component-library-v1.2.3.css">
<script src="https://your-cdn-url/path/to/cdn/your-component-library-v1.2.3.js"></script>

⒌异步加载: 在一些情况下,你可能希望异步加载组件库,以避免阻塞页面加载。

<script>
  function loadComponentLibrary() {
    const script = document.createElement('script');
    script.src = 'https://your-cdn-url/path/to/cdn/your-component-library.js';
    document.head.appendChild(script);
  }
  window.onload = loadComponentLibrary;
</script>