前端插件封装,如何将插件打包成npm包,

开发过程中,我们经常自己二次封装UI组件,或者自己封装一些方便开发的插件,为了方便团队成员也可以使用我们封装的插件,可以将插件单独打包成npm包,并在项目的package.json中配置好插件的信息,这样,在项目npm install安装依赖的时候,就可以将插件顺便安装下来,并引用。

以下是我在开发过程中,二次封装element-plus,并单独打包成npm包引用的示例。

1、将element plus的源码从git上拉取下来,git地址:GitHub - element-plus/element-plus: A Vue.js 3 UI Library made by Element team

2、根据自己项目需求修改或者二次封装UI组件(此处不做详细介绍);

3、将修改好的element plus项目进行打包,npm run build(element plus是基于pnpm打包的,如果本地未安装 pnpm,需安装pnpm,地址:安装 | pnpm中文文档 | pnpm中文网);

4、打包完成后,会在根目录下生成dist文件,结构如下图:

前端插件封装,如何将插件打包成npm包,_第1张图片

 5、完成打包后,我们就要进行下一步操作,cd进入打包好的dist文件夹下的element-plus*,将其打成npm压缩包,在此之前我们需要进行一些配置。

要npm init生成一个package.json。并更新必要字段,下面是详细代码(需注意配置顺序):

{
  "name": "element-plus-example",  //这里需要写和element-plus不一样的名字,防止冲突
  "version": "2.3.9",  //版本号
  "description": "A Component Library for Vue 3",  //介绍
  "keywords": [
    "element-plus",
    "element",
    "component library",
    "ui framework",
    "ui",
    "vue"
  ],
  "homepage": "https://element-plus.org/",
  "bugs": {
    "url": "https://github.com/element-plus/element-plus/issues"
  },
  "license": "MIT",
  "main": "lib/index.js",  //入口文件
  "module": "es/index.mjs",
  "types": "es/index.d.ts",
  "exports": {
    ".": {
      "types": "./es/index.d.ts",
      "import": "./es/index.mjs",
      "require": "./lib/index.js"
    },
    "./es": {
      "types": "./es/index.d.ts",
      "import": "./es/index.mjs"
    },
    "./lib": {
      "types": "./lib/index.d.ts",
      "require": "./lib/index.js"
    },
    "./es/*.mjs": {
      "types": "./es/*.d.ts",
      "import": "./es/*.mjs"
    },
    "./es/*": {
      "types": [
        "./es/*.d.ts",
        "./es/*/index.d.ts"
      ],
      "import": "./es/*.mjs"
    },
    "./lib/*.js": {
      "types": "./lib/*.d.ts",
      "require": "./lib/*.js"
    },
    "./lib/*": {
      "types": [
        "./lib/*.d.ts",
        "./lib/*/index.d.ts"
      ],
      "require": "./lib/*.js"
    },
    "./*": "./*"
  },
  "unpkg": "dist/index.full.js",
  "jsdelivr": "dist/index.full.js",
  "repository": {
    "type": "git",
    "url": "git+https://github.com/element-plus/element-plus.git"
  },
  "publishConfig": {
    "access": "public"
  },
  "style": "dist/index.css",
  "sideEffects": [
    "dist/*",
    "theme-chalk/**/*.css",
    "theme-chalk/src/**/*.scss",
    "es/components/*/style/*",
    "lib/components/*/style/*"
  ],
  "peerDependencies": {
    "vue": "^3.2.0"
  },
  "dependencies": {
    "@ctrl/tinycolor": "^3.4.1",
    "@element-plus/icons-vue": "^2.0.6",
    "@floating-ui/dom": "^1.0.1",
    "@popperjs/core": "npm:@sxzz/popperjs-es@^2.11.7",
    "@types/lodash": "^4.14.182",
    "@types/lodash-es": "^4.17.6",
    "@vueuse/core": "^9.1.0",
    "async-validator": "^4.2.5",
    "dayjs": "^1.11.3",
    "escape-html": "^1.0.3",
    "lodash": "^4.17.21",
    "lodash-es": "^4.17.21",
    "lodash-unified": "^1.0.2",
    "memoize-one": "^6.0.0",
    "normalize-wheel-es": "^1.2.0"
  },
  "devDependencies": {
    "@types/node": "*",
    "csstype": "^2.6.20",
    "vue": "^3.2.37",
    "vue-router": "^4.0.16"
  },
  "vetur": {
    "tags": "tags.json",
    "attributes": "attributes.json"
  },
  "web-types": "web-types.json",
  "browserslist": [
    "> 1%",
    "not ie 11",
    "not op_mini all"
  ],
  "gitHead": "8b083b454e966f4812852992b9c618e0ba68c8f5"
}

配置global.d.ts文件,它用于定义全局变量、全局类型和全局模块,以便在整个项目中使用。 下面是详细代码:

// GlobalComponents for Volar
declare module '@vue/runtime-core' {
  export interface GlobalComponents {
    ElAffix: typeof import('element-plus')['ElAffix']
    ElAlert: typeof import('element-plus')['ElAlert']
    ElAside: typeof import('element-plus')['ElAside']
    ElAutocomplete: typeof import('element-plus')['ElAutocomplete']
    ElAvatar: typeof import('element-plus')['ElAvatar']
    ElBacktop: typeof import('element-plus')['ElBacktop']
    ElBadge: typeof import('element-plus')['ElBadge']
    ElBreadcrumb: typeof import('element-plus')['ElBreadcrumb']
    ElBreadcrumbItem: typeof import('element-plus')['ElBreadcrumbItem']
    ElButton: typeof import('element-plus')['ElButton']
    ElButtonGroup: typeof import('element-plus')['ElButtonGroup']
    ElCalendar: typeof import('element-plus')['ElCalendar']
    ElCard: typeof import('element-plus')['ElCard']
    ElCarousel: typeof import('element-plus')['ElCarousel']
    ElCarouselItem: typeof import('element-plus')['ElCarouselItem']
    ElCascader: typeof import('element-plus')['ElCascader']
    ElCascaderPanel: typeof import('element-plus')['ElCascaderPanel']
    ElCheckbox: typeof import('element-plus')['ElCheckbox']
    ElCheckboxButton: typeof import('element-plus')['ElCheckboxButton']
    ElCheckboxGroup: typeof import('element-plus')['ElCheckboxGroup']
    ElCol: typeof import('element-plus')['ElCol']
    ElCollapse: typeof import('element-plus')['ElCollapse']
    ElCollapseItem: typeof import('element-plus')['ElCollapseItem']
    ElCollapseTransition: typeof import('element-plus')['ElCollapseTransition']
    ElColorPicker: typeof import('element-plus')['ElColorPicker']
    ElContainer: typeof import('element-plus')['ElContainer']
    ElConfigProvider: typeof import('element-plus')['ElConfigProvider']
    ElDatePicker: typeof import('element-plus')['ElDatePicker']
    ElDialog: typeof import('element-plus')['ElDialog']
    ElDivider: typeof import('element-plus')['ElDivider']
    ElDrawer: typeof import('element-plus')['ElDrawer']
    ElDropdown: typeof import('element-plus')['ElDropdown']
    ElDropdownItem: typeof import('element-plus')['ElDropdownItem']
    ElDropdownMenu: typeof import('element-plus')['ElDropdownMenu']
    ElEmpty: typeof import('element-plus')['ElEmpty']
    ElFooter: typeof import('element-plus')['ElFooter']
    ElForm: typeof import('element-plus')['ElForm']
    ElFormItem: typeof import('element-plus')['ElFormItem']
    ElHeader: typeof import('element-plus')['ElHeader']
    ElIcon: typeof import('element-plus')['ElIcon']
    ElImage: typeof import('element-plus')['ElImage']
    ElImageViewer: typeof import('element-plus')['ElImageViewer']
    ElInput: typeof import('element-plus')['ElInput']
    ElInputNumber: typeof import('element-plus')['ElInputNumber']
    ElLink: typeof import('element-plus')['ElLink']
    ElMain: typeof import('element-plus')['ElMain']
    ElMenu: typeof import('element-plus')['ElMenu']
    ElMenuItem: typeof import('element-plus')['ElMenuItem']
    ElMenuItemGroup: typeof import('element-plus')['ElMenuItemGroup']
    ElOption: typeof import('element-plus')['ElOption']
    ElOptionGroup: typeof import('element-plus')['ElOptionGroup']
    ElPageHeader: typeof import('element-plus')['ElPageHeader']
    ElPagination: typeof import('element-plus')['ElPagination']
    ElPopconfirm: typeof import('element-plus')['ElPopconfirm']
    ElPopper: typeof import('element-plus')['ElPopper']
    ElPopover: typeof import('element-plus')['ElPopover']
    ElProgress: typeof import('element-plus')['ElProgress']
    ElRadio: typeof import('element-plus')['ElRadio']
    ElRadioButton: typeof import('element-plus')['ElRadioButton']
    ElRadioGroup: typeof import('element-plus')['ElRadioGroup']
    ElRate: typeof import('element-plus')['ElRate']
    ElRow: typeof import('element-plus')['ElRow']
    ElScrollbar: typeof import('element-plus')['ElScrollbar']
    ElSelect: typeof import('element-plus')['ElSelect']
    ElSlider: typeof import('element-plus')['ElSlider']
    ElStep: typeof import('element-plus')['ElStep']
    ElSteps: typeof import('element-plus')['ElSteps']
    ElSubMenu: typeof import('element-plus')['ElSubMenu']
    ElSwitch: typeof import('element-plus')['ElSwitch']
    ElTabPane: typeof import('element-plus')['ElTabPane']
    ElTable: typeof import('element-plus')['ElTable']
    ElTableColumn: typeof import('element-plus')['ElTableColumn']
    ElTabs: typeof import('element-plus')['ElTabs']
    ElTag: typeof import('element-plus')['ElTag']
    ElText: typeof import('element-plus')['ElText']
    ElTimePicker: typeof import('element-plus')['ElTimePicker']
    ElTimeSelect: typeof import('element-plus')['ElTimeSelect']
    ElTimeline: typeof import('element-plus')['ElTimeline']
    ElTimelineItem: typeof import('element-plus')['ElTimelineItem']
    ElTooltip: typeof import('element-plus')['ElTooltip']
    ElTransfer: typeof import('element-plus')['ElTransfer']
    ElTree: typeof import('element-plus')['ElTree']
    ElTreeV2: typeof import('element-plus')['ElTreeV2']
    ElTreeSelect: typeof import('element-plus')['ElTreeSelect']
    ElUpload: typeof import('element-plus')['ElUpload']
    ElSpace: typeof import('element-plus')['ElSpace']
    ElSkeleton: typeof import('element-plus')['ElSkeleton']
    ElSkeletonItem: typeof import('element-plus')['ElSkeletonItem']
    ElStatistic: typeof import('element-plus')['ElStatistic']
    ElCheckTag: typeof import('element-plus')['ElCheckTag']
    ElDescriptions: typeof import('element-plus')['ElDescriptions']
    ElDescriptionsItem: typeof import('element-plus')['ElDescriptionsItem']
    ElResult: typeof import('element-plus')['ElResult']
    ElSelectV2: typeof import('element-plus')['ElSelectV2']
  }

  interface ComponentCustomProperties {
    $message: typeof import('element-plus')['ElMessage']
    $notify: typeof import('element-plus')['ElNotification']
    $msgbox: typeof import('element-plus')['ElMessageBox']
    $messageBox: typeof import('element-plus')['ElMessageBox']
    $alert: typeof import('element-plus')['ElMessageBox']['alert']
    $confirm: typeof import('element-plus')['ElMessageBox']['confirm']
    $prompt: typeof import('element-plus')['ElMessageBox']['prompt']
    $loading: typeof import('element-plus')['ElLoadingService']
  }
}

export {}

 6、加上上面两个文件之后,用命令:npm pack进行压缩,会生成一个名称为 package.json中名称+版本号的压缩包,dist目录变为下图:

前端插件封装,如何将插件打包成npm包,_第2张图片

 7、这时我们可以直接将生成的npm包(压缩包)上传到npm(这个需要注册npm账号,并开通业务),或者上传到私有cnpm服务器(详细操作:cnpm 登录注册 发布 查看 更新等操作记录 - 简书),或者简单粗暴直接复制到项目的根目录,并在所用项目的package.json中配置依赖位置(详细操作:如何在项目中引用本地的npm包_海豹先生_的博客-CSDN博客)

这样就可以在项目下载依赖的时候,将插件的依赖包下载到项目中并使用。

你可能感兴趣的:(npm,前端,node.js)