使用Vue+Vite+Ts+Jsx封装组件,发布NPM包

776 阅读2分钟

项目做多了,就想提高生产力,封装常用的组件,发布NPM包,供以后调用。就像Element-Plus,Naive-UI样,搞一个自己的UI组件库。这篇博文主要说明怎么配置一个组件项目,发布npm.

1. 用vitevue-ts模版新建项目

执行命令pnpm create vite camellia --template vue-ts,创建了一个camellia的项目

image.png

2. 安装@vitejs/plugin-vue" 因为要用jsx封装组件,执行pnpm i -D @vitejs/plugin-vue-jsx
3. 在src目录下新建一个table/Table.tsx,这是要发布的表格组件
import { defineComponent } from "vue";

export default defineComponent({
  name: "TableComponent",
  props: {
    data: {
      type: Array as () => Array<{ [key: string]: any }>,
      required: true,
    },
  },

  // return renderTable
  setup(props) {
    return () => (
      <div>
        <table>
          <thead>
            <tr>
              {Object.keys(props.data[0]).map((key) => (
                <th key={key}>{key}</th>
              ))}
            </tr>
          </thead>
          <tbody>
            {props.data.map((item, index) => (
              <tr key={index}>
                {Object.values(item).map((value, key) => (
                  <td key={key}>{value}</td>
                ))}
              </tr>
            ))}
          </tbody>
        </table>
      </div>
    );
  },
});

可以看到jsx部分VSCode提示 JSX element implicitly has type 'any' because no interface 'JSX.IntrinsicElements' exists.ts(7026)

image.png 我用的是vue是3.4.27,自从vue3.4版本,不再全局注册jsx,需要自己加配置,参考官网

image.png

image.png

4. 在src 目录下新建index.ts作为项目的主入口文件
import TableComponent from "./table/Table";
export { TableComponent };

先本地运行下项目,在App.vue引入Table.tsx,看下能不能访问

image.png

5. 配置vite.config.tsbuild,打包目录,组件库入口
import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";
import vueJsx from "@vitejs/plugin-vue-jsx";
// https://vitejs.dev/config/
export default defineConfig({
  plugins: [vue(), vueJsx()],
  build: {
    lib: {
      entry: "./src/index.ts",
      name: "CamelliaUI",
      fileName: (format) => `camellia-ui.${format}.js`,
    },
    rollupOptions: {
      // Ensure external dependencies are not bundled into your library
      external: ["vue"],
      output: {
        globals: {
          vue: "Vue",
        },
      },
    },
  },
});
6. 配置package.json, 版本,作者,描述,项目入口等等
{
  "name": "camellia-ui",
  "version": "0.0.716",
  "description": "A UI library for VueJS",
  "type": "module",
  "keywords": [
    "UI"
  ],
  "author": "gongzemin",
  "license": "MIT",
  "scripts": {
    "dev": "vite",
    "build": "vue-tsc && vite build",
    "preview": "vite preview"
  },
  "dependencies": {
    "vue": "^3.4.21"
  },
  "devDependencies": {
    "@vitejs/plugin-vue": "^5.0.4",
    "@vitejs/plugin-vue-jsx": "^3.1.0",
    "typescript": "^5.2.2",
    "vite": "^5.2.0",
    "vue-tsc": "^2.0.6"
  }
}
7. 执行构建命令 npm run build

image.png

8. 发布npm 需要先npm login 然后npm publish

image.png

9. 安装包,验证下

image.png

代码已经放到github, 方便参考

后记:那个App.vue我留着主要是本地测试用,应该要安装测试包来测试的,真正的UI组件库对于目前的 我还是很复杂,现在只是先走一下组件包的流程。