前端工程化 搭建私有组件库 组件从开发到发布私有npm仓库的全过程

前言

基于Vue3.0 + TS的组件从开发组件库到发布私有npm仓库的全过程

环境

这里列出本文所使用的环境版本

vue 3.0

vue/cli 4.5.9

nodeJs 14.15.1

npm 6.14.8

vue –version

@vue/cli 4.5.9

npm -v

6.14.8

node -v

v14.15.1

步骤

  1. 创建项目

    使用 vue-cli 创建一个 vue3 项目,假设项目名为 avatar-ui-vue

vue create avatar-ui-vue

选择自定义Manually select features,回车进入下一步

选中Choose Vue version、Babel 、TypeScript、 CSS Pre-processors 这4项,回车进入下一步

Choose a version of Vue.js that you want to start the project with 选择 3.x (Preview)

Use class-style component syntax? 输入n

Use Babel alongside TypeScript (required for modern mode, auto-detected polyfills, transpiling JSX)? 输入y

Pick a CSS pre-processor (PostCSS, Autoprefixer and CSS Modules are supported by default) 选择 Sass/SCSS (with dart-sass)

Where do you prefer placing config for Babel, ESLint, etc.? 选择 In dedicated config files

Save this as a preset for future projects? 输入y,回车后输入模板名保存模板

最后回车,等待项目创建完成

创建完成,目录结构如图

  1. 规划目录

    ├─ build // 编辑打包脚本目录,用于存放脚本文件

    │ ├─ rollup.config.js

    ├─ docs // 文档目录,用于生成 vuepress 文档页面

    │ ├─ .vuepress

    │ ├─ guide

    │ ├─ README.md

    ├─ examples // 原 src 目录,改成 examples 用于示例展示

    │ ├─ App.vue

    │ ├─ main.ts

    ├─ packages // 新增 packages 目录,用于编写存放组件,如button

    │ ├─ button

    │ ├─ index.ts

    ├─ typings // 新增 typings 目录,用于存放 .d.ts 文件,把shims-vue.d.ts移到这里

    │ ├─ shims-vue.d.ts

    ├─ .npmignore // 新增 .npmignore 配置文件

    ├─ vue.config.js // 新增 vue.config.js 配置文件

将 src 目录改为 examples ,并将里面的 assets 和 components 目录删除,移除 App.vue 里的组件引用。

调整后的目录结构如图

  1. 项目配置

    3.1 vue.config.js

新增 vue.config.js 配置文件,适配重新规划后的项目目录

const path = require(‘path’)

module.exports = {

// 修改 pages 入口

pages: {

index: {

entry: “examples/main.ts”, //入口

template: “public/index.html”, //模板

filename: “index.html” //输出文件

}

},

// 扩展 webpack 配置

chainWebpack: (config) => {

// 新增一个 ~ 指向 packages 目录, 方便示例代码中使用

config.resolve.alias

.set(‘~’, path.resolve(‘packages’))

}

}

3.2 .npmignore

新增 .npmignore 配置文件,组件发布到 npm 中,只有编译后的发布目录(例如lib)、package.json、README.md才是需要被发布的,所以我们需要设置忽略目录和文件

忽略目录

.idea

.vscode

build/

docs/

examples/

packages/

public/

node_modules/

typings/

忽略指定文件

babel.config.js

tsconfig.json

tslint.json

vue.config.js

.gitignore

.browserslistrc

*.map

3.3 tsconfig.json

修改 tsconfig.json 中 paths 的路径

"paths": {
  "@/*": [
    "src/*"
  ]
}

改为

"paths": {
  "~/*": [
    "packages/*"
  ]
}

修改 include 的路径

“include”: [

“src//*.ts”,

“src//.tsx”,

“src/**/.vue”,

“tests//*.ts”,

“tests//*.tsx”

]

改为

“include”: [

“examples//*.ts”,

“examples//.tsx”,

“examples/**/.vue”,

“packages//*.ts”,

“packages//.tsx”,

“packages/**/.vue”,

“typings//*.ts”,

“tests//.ts”,

“tests/**/.tsx”

]

3.4 package.json

修改 package.json 中发布到 npm 的字段

name:包名,该名字是唯一的。可在 npm 官网搜索名字,如果存在则需换个名字。

version:版本号,每次发布至 npm 需要修改版本号,不能和历史版本号相同。

description:描述。

main:入口文件,该字段需指向我们最终编译后的包文件。

typings:types文件,TS组件需要。

keyword:关键字,以空格分离希望用户最终搜索的词。

author:作者信息

private:是否私有,需要修改为 false 才能发布到 npm

license: 开源协议

参考设置:

{

“name”: “avatar-ui-vue”,

“version”: “0.1.0”,

“private”: false,

“description”: “基于vue3+vant的前端组件库”,

“main”: “lib/index.min.js”,

“module”: “lib/index.esm.js”,

“typings”: “lib/index.d.ts”,

“keyword”: “vue3 vant”,

“license”: “MIT”,

“author”: {

“name”: “yourname”,

“email”: “youremail@126.com”

}

}

在 package.json 的 scripts 新增编译和发布的命令

“scripts”: {

“build”: “yarn build:clean && yarn build:lib && yarn build:esm-bundle && rimraf lib/demo.html”,

“build:clean”: “rimraf lib”,

“build:lib”: “vue-cli-service build –target lib –name index –dest lib packages/index.ts”,

“build:esm-bundle”: “rollup –config ./build/rollup.config.js”

}

其中 build:lib 是利用 vue-cli 进行 umd 方式打包,build:esm-bundle 是利用 rollup 进行 es 方式打包,具体参数解析如下:

–target: 构建目标,默认为应用模式。改为 lib 启用库模式。

–name: 输出文件名

–dest : 输出目录,默认 dist。改成 lib

[entry]: 入口文件路径,默认为 src/App.vue。这里我们指定编译 packages/ 组件库目录。

以下是完整package.json参考示例

{

“name”: “avatar-ui-vue”,

“version”: “0.1.0”,

“private”: false,

“description”: “基于vue3+vant的前端组件库”,

“main”: “lib/index.min.js”,

“module”: “lib/index.esm.js”,

“typings”: “lib/index.d.ts”,

“keyword”: “vue3 vant”,

“license”: “MIT”,

“author”: {

“name”: “zh”,

“email”: “”

},

“scripts”: {

“serve”: “vue-cli-service serve”,

“docs:dev”: “vuepress dev docs”,

“docs:build”: “vuepress build docs”,

“build”: “yarn build:clean && yarn build:lib && yarn build:esm-bundle && rimraf lib/demo.html”,

“build:clean”: “rimraf lib”,

“build:lib”: “vue-cli-service build –target lib –name index –dest lib packages/index.ts”,

“build:esm-bundle”: “rollup –config ./build/rollup.config.js”

},

“dependencies”: {

“core-js”: “^3.6.5”,

“vue”: “^3.0.0”

},

“devDependencies”: {

“@rollup/plugin-node-resolve”: “^13.0.5”,

“@vue/cli-plugin-babel”: “~4.5.0”,

“@vue/cli-plugin-typescript”: “~4.5.0”,

“@vue/cli-service”: “~4.5.0”,

“@vue/compiler-sfc”: “^3.0.0”,

“rollup”: “^2.58.0”,

“rollup-plugin-terser”: “^7.0.2”,

“rollup-plugin-typescript2”: “^0.30.0”,

“rollup-plugin-vue”: “^6.0.0”,

“sass”: “^1.26.5”,

“sass-loader”: “^8.0.2”,

“typescript”: “~4.1.5”

}

}

3.5 rollup.config.js

新增 rollup.config.js,rollup 打包脚本

// import vue from ‘rollup-plugin-vue’

import { nodeResolve } from ‘@rollup/plugin-node-resolve’

import path from ‘path’

// import commonjs from ‘@rollup/plugin-commonjs’

import { terser } from ‘rollup-plugin-terser’

import typescript from ‘rollup-plugin-typescript2’

import pkg from ‘…/package.json’

const deps = Object.keys(pkg.dependencies)

// eslint-disable-next-line @typescript-eslint/no-var-requires

const vue = require(‘rollup-plugin-vue’)

export default [

{

input: path.resolve(__dirname, ‘…/packages/index.ts’),

output: [

{

format: ‘es’,

file: pkg.module,

}

],

plugins: [

terser(),

nodeResolve(),

// commonjs(),

vue({

target: ‘browser’,

css: false,

exposeFilename: false,

}),

typescript({

tsconfigOverride: {

compilerOptions: {

declaration: true,

},

‘include’: [

‘packages//*’,

‘typings/shims-vue.d.ts’,

],

‘exclude’: [

‘node_modules’,

‘packages//tests/*’,

],

},

abortOnError: false,

}),

],

external(id) {

return /^vue/.test(id)

|| deps.some(k => new RegExp(‘^’ + k).test(id))

},

},

]

  1. 开发组件

    下面以Button组件作为开发示例,在 packages 目录下新建 index.ts 文件和 button 文件夹,在 button 下新建 index.ts 和 src/button.vue,结构如图

button.vue

button/index.ts,单独组件的入口文件,在其他项目可以使用 import { xxx } from ‘nandit-vue-vant’ 方式进行单个组件引用

import { App } from ‘vue’

import Button from ‘./src/button.vue’

// 定义 install 方法, App 作为参数

Button.install = (app: App): void => {

app.component(Button.name, Button)

}

export default Button

index.ts 作为组件库的入口文件,可以在其他项目的 main.ts 引入整个组件库,内容如下

import { App } from ‘vue’

import NdButton from ‘./button’

// 所有组件列表

const components = [ NdButton ]

// 定义 install 方法, App 作为参数

const install = (app: App): void => {

// 遍历注册所有组件

components.map((component) => app.component(component.name, component))

}

export {

NdButton

}

export default {

install

}

这样,我们就完成一个简单的 button 组件,后续需要扩展其他组件,按照 button 的结构进行开发,并且在 index.ts 文件中 components 组件列表添加即可。

  1. 编写示例

    组件开发完成后,我们本地先测试一下,没有问题再发布到 npm 仓库。在示例入口 main.ts 引用我们的组件库

import { createApp } from ‘vue’

import App from ‘./App.vue’

import NanditVue from ‘~/index’ // 这里 ~ 就是在 tsconfig.json 以及 vue.config.js 配置的 packages 路径

const app = createApp(App)

app.use(NanditVue)

app.mount(‘#app’)

App.vue 删除项目初始化的 HelloWorld 组件

组件示例

{{ count }}

启动项目,测试看看

yarn serve

  1. 发布组件

    组件开发并测试通过后,就可以发布到 npm 仓库提供给其他项目使用了,首先执行编译库命令,生成 lib 目录

yarn build

6.1 发布到npm官网

6.1.1 注册npm账号

前往官网注册 npm 账号,如果已注册过,则跳过此步骤

6.1.2 登录npm账号

在项目中 terminal 命令窗口登录 npm 账号

npm login

Username:

Password:

Email:(this IS public)

输入在 npm 注册的账号、密码、邮箱

6.1.3 发布

确保 registry 是 https://registry.npmjs.org

npm config get registry

如果不是则先修改 registry

npm config set registry=https://registry.npmjs.org

然后执行命令

npm publish

如果需要删除已发布的组件(不推荐删除已发布的组件),则执行以下命令(加 –force 强制删除)

npm unpublish –force

删除指定版本的包,比如包名为 nandit-vue-vant 版本 0.1.0

npm unpublish nandit-vue-vant@0.1.0

如果24小时内有删除过同名的组件包,那么将会发布失败,提示

npm ERR! code E403

npm ERR! 403 403 Forbidden – PUT https://registry.npmjs.org/

npm ERR! 403 In most cases, you or one of your dependencies are requesting

npm ERR! 403 a package version that is forbidden by your security policy.

npm ERR! A complete log of this run can be found in:

npm ERR! D:\tools\nodejs\node_cache_logs\2021-10-18T09_58_58_933Z-debug.log

只能换一个名称发布或者等24小时之后发布,所以不要随便删除已发布的组件(万一有项目已经引用)

在这里插入图片描述

搭建npm私库

1、安装verdaccio

首先电脑上要安装有nodejs

windows+r cmd 之后

npm install -g verdaccio

1

如下图所示:安装完成后如果没有提示错误则表示安装

2、启动verdaccio

3、修改配置文件 config.yaml

3.1 在配置文件的末尾添加listen: 0.0.0.0:4873【配置此选项则是允许任何外部的所有IP都可以访问到此服务】

使用本地库

verdaccio 服务启动完成后可通过 nrm 工具进行源地址切换

全局安装 nrm

$ npm install -g nrm

1

2

安装完成后通过如下命令查看已有配置

$ nrm ls

报错require open的话把这一行注释掉

  • npm ———- https://registry.npmjs.org/

    yarn ——— https://registry.yarnpkg.com/

    tencent —— https://mirrors.cloud.tencent.com/npm/

    cnpm ——— https://r.cnpmjs.org/

    taobao ——- https://registry.npmmirror.com/

    npmMirror —- https://skimdb.npmjs.com/registry/

添加本地库至 nrm 配置列表

添加配置项

nrm add zh http://localhost:4873

切换 npm 源至私库

nrm use zh

添加环境用户并根据提示输入用户名密码,为后续传包做准备 (重要)

添加配置项

nrm add zh http://localhost:4873

切换 npm 源至私库

nrm use zh

添加环境用户并根据提示输入用户名密码,为后续传包做准备 (重要)

npm adduser –registry http://localhost:4873/

添加配置项

nrm add localNpm http://localhost:4873

切换 npm 源至私库

nrm use localNpm

直接发布

$ npm publish

或指定源

$ npm publish –registry http://localhost:4873

在这里插入图片描述

至此简单环境配置完毕

本文来自网络,不代表协通编程立场,如若转载,请注明出处:https://net2asp.com/d8bb164ff4.html