搭建一个组件库(vue3)

1.Monorepo (单仓库,多项目)

作用:在一个项目里面管理多个模块,并且互不干扰

npm install pnpm -g

2.初始化 package.json

pnpm init

3.新建配置文件 .npmrc

//扁平化依赖  解决幽灵依赖的问题
shamefully-hoist = true

4.新建pnpm-workspace.yaml

仿照elemen-ui

packages:
    - 'packages/**'
    - 'examples'

5.安装依赖

pnpm i vue@next typescript less -D -w

-D和--save-dev功能一样  

-w命令用于在多个项目中同时执行命令。可以使用该命令来在多个项目中安装依赖项或运行脚本等操作。

6.配置 tsconfit.json

npx tsc --init

{
  "compilerOptions": {
    "allowJs": true, //允许编译器编译JS,JSX文件
    "target": "ES2015", //指定ECMAScript目标版本
    "useDefineForClassFields": true,
    "module": "ESNext", //设置程序的模块系统
    "moduleResolution": "Node", //模块解析策略。默认使用node的模块解析策略
    "strict": true, //启用所有严格类型检查选项
    "jsx": "preserve", //preserve模式,在preserve模式下生成代码中会保留JSX以供后续的转换操作使用
    "sourceMap": true, //生成目标文件的sourceMap文件
    "resolveJsonModule": true, //允许导入扩展名为“.json”的模块
    "esModuleInterop": false, //允许module.exports=xxx 导出,由import from 导入.因为很多老的js库使用了commonjs的导出方式,并且没有导出default属性
    "lib": [ //TS需要引用的库
      "ESNext",
      "DOM"
    ],
    "forceConsistentCasingInFileNames": true, //禁止对同一个文件的不一致的引用
    "allowSyntheticDefaultImports": true, //允许从没有设置默认导出的模块中默认导入
    "skipLibCheck": true, //忽略所有的声明文件( *.d.ts)的类型检查
    "baseUrl": "./", // 解析非相对模块的基地址,默认是当前目录
    "paths": { //模块名到基于 baseUrl的路径映射的列表
      "/@/*": [
        "src/*"
      ],
    },
    "types": [ //要包含的类型声明文件名列表
      "vite/client",
      "element-plus/global",
    ]
  },
  "include": [ //包含的文件
    "src/**/*.ts",
    "src/**/*.d.ts",
    "src/**/*.tsx",
    "src/**/*.js",
    "src/**/*.jsx",
    "src/**/*.vue",
  ]
}

7.初始化 examples仓库

examples 文件夹
1.执行
pnpm init

2.安装 vite 和 @vitejs/plugin-vue
pnpm install vite @vitejs/plugin-vue -D -w

3.新建vite.config.ts 并配置 

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
export default defineConfig({
    plugins:[vue()]
})

4.新建index.html文件



  
    
    
    
    Document
  
  
    
注意: vite 是基于 esmodule 的 所以 type="module" @vitejs/plugin-vue 会默认加载 examples 下的 index.html 5.新建app.vue 6.新建main.ts import {createApp} from 'vue' import App from './app.vue' const app = createApp(App) app.mount('#app') 7.因为直接引入.vue 文件 TS 会找不到对应的类型声明;所以需要新建 typings(命名没有明确规定,TS 会自动寻找.d.ts 文件)文件夹来专门放这些声明文件。 declare module '*.vue' {     import type { DefineComponent } from "vue";     const component:DefineComponent<{},{},any> } 8.在package.json 文件中配置 scripts 脚本 "scripts": { "dev": "vite" }, 9.pnpm run dev 启动项目

8.初始化 components仓库

components 文件夹

1.目录结构
-- components
   
  -- src
    -- index.ts
    -- button
     -- button.vue
     -- index.ts
-- index.ts
-- package.json


2.button.vue 


3.button/index.ts
export * from "./button.vue";
import type { App } from "vue";
import Button from "./button.vue";
Button.install = (app: App): void => {
  app.component("Button", Button);
};
export { Button };
export default Button;


4.src/index.ts
export * from './button'

5.components/index.ts
export * from "./src";
import * as components from './src';
import { App } from 'vue';
export default {
    install: (app: App) => {
      for (const c in components) {
        app.use(components[c]);
      }
    }
  };


  9.在examples仓库使用组件

examples 文件夹

1.pnpm i packages文件下的package.json的name
 生成软链接

2.使用
 //局部注入 app.vue 页面
 import { Button } from "ui库name";

//全局注入
import demoUi from 'demo-uii'
app.use(demoUi);

10.在components库打包组件

 components 文件夹 新建vite.config.ts

这里我们选择打包cjs(CommonJS)和esm(ESModule)两种形式,cjs模式主要用于服务端引用(ssr),而esm就是我们现在经常使用的方式,它本身自带treeShaking而不需要额外配置按需引入(前提是你将模块分别导出),非常好用~

import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";
export default defineConfig({
  build: {
    //打包文件目录
    outDir: "es",
    //压缩
    //minify: false,
    rollupOptions: {
      //忽略打包vue文件
      external: ["vue"],
      input: ["index.ts"],
      output: [
        {
          //打包格式
          format: "es",
          //打包后文件名
          entryFileNames: "[name].mjs",
          //让打包目录和我们目录对应
          preserveModules: true,
          exports: "named",
          //配置打包根目录
          dir: "../mimi-ui/es",
        },
        {
          //打包格式
          format: "cjs",
          //打包后文件名
          entryFileNames: "[name].js",
          //让打包目录和我们目录对应
          preserveModules: true,
          exports: "named",
          //配置打包根目录
          dir: "../mimi-uii/lib",
        },
      ],
    },
    lib: {
      entry: "./index.ts",
    },
  },
  plugins: [vue()],
});

tip:到这里其实打包的组件库只能给 js 项目使用,在 ts 项目下运行会出现一些错误,而且使用的时候还会失去代码提示功能,要做出下面处理

功能:自动生成类型声明文件

pnpm add [email protected] -D -w

 配置vite.config.ts

import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";
import dts from "vite-plugin-dts";
import DefineOptions from "unplugin-vue-define-options/vite";
export default defineConfig({
  plugins: [
    vue(),
    dts({
      entryRoot: "./src",
      outputDir: ["../mimi-uii/es/src", "../mimi-uii/lib/src"],
      //指定使用的tsconfig.json为我们整个项目根目录下,如果不配置,你也可以在components下新建tsconfig.json
      tsConfigFilePath: "../../tsconfig.json",
    }),
    DefineOptions(),
 
  ],
});

配置完成在package.json 配置并运行

"scripts": {
    "build": "vite build"
  },

11.在打包目录下init 并且修改参数


{
  "name": "mimi-uii",
  "version": "1.0.7",
  "main": "lib/index.js",
  "module": "es/index.mjs",
  "files": [
    "es",
    "lib"
  ],
  "keywords": [
    "mimi-uii",
    "vue3组件库"
  ],
  "sideEffects": [
    "**/*.css"
  ],
  "author": "",
  "license": "MIT",
  "description": "",
  "typings": "lib/index.d.ts"
}

12.登陆npmjs

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

13.发布

npm publish

14.搭建文档库(vitepress)

   1.目录 docs下

pnpm init
pnpm install -D vitepress vue

  2.安装完成之后,新建 docs/index.md 文件

---
layout: home

title: eli-code-ui
titleTemplate: 一个快速搭建Vue3组件库的框架

hero:
  name: eli-code-ui
  text: 一个快速搭建Vue3组件库的框架
  tagline: 让你的组件库开发更简单
  image:
    /src: /logo.png
    alt: eli-code-ui
  actions:
    - theme: brand
      text: 开始
      link: /guild/introduce
    - theme: alt
      text: 在 GitHub 上查看
features:
  - icon: 
    title: Vue3组件库
    details: 基于vite+TypeScript开发
  - icon: 
    title: 让你的组件库开发更简单
    details: 提供一个Vue3组件库开发环境
  - icon: ️
    title: 按需引入
    details: 直接支持按需引入无需配置任何插件。
---

  3.然后 package.json 中新增scripts命令

"scripts": {
    "docs:dev": "vitepress dev docs",
    "docs:build": "vitepress build docs",
    "docs:preview": "vitepress preview docs"
  },

15.vitepress 配置

 1.在 docs/.vitepress 目录下新建config.js

export default {
  themeConfig: {
    siteTitle: "vitepress",
    nav: [
      { text: "组件", link: "/components/button/" },
    ],
  },
};

  2.设置侧边栏

sidebar: {
            "/components/": [
                {
                    text: "基础组件",
                    items: [
                        {
                            text: "Button",
                            link: "/components/button/",
                        }, {
                            text: "icon",
                            link: "/components/icon/",
                        }
                    ],
                }
            ]
 },

 3.然后 site 目录下安装pnpm add mimi-uii,在 docs 下新建 theme/index.js引入我们的组件库

import DefaultTheme from "vitepress/theme";
import mimiUii from "mimi-uii";
import 'mimi-uii/style.css' //打包设置出可以进行打包处理
export default {
  ...DefaultTheme,
  enhanceApp: async ({ app }) => {
    // app is the Vue 3 app instance from `createApp()`. router is VitePress'
    // custom router. `siteData`` is a `ref`` of current site-level metadata.
    app.use(mimiUii);
  },
};

16.打包文档库

pnpm run docs:deploy

  打包完了之后在docs/.vitepress/dist目录

你可能感兴趣的:(vue.js,前端,javascript)