vite 组件库工程化 —— 搭建开发环境

342 阅读4分钟

创建项目,使用pnpm进行初始化

performant npm ,意味“高性能的 npm”。pnpm由npm/yarn衍生而来,解决了npm/yarn内部潜在的bug,极大的优化了性能,扩展了使用场景。被誉为“最先进的包管理工具

mkdir component-vite                         
cd component-vite 
pnpm init

搭建调试环境

使用 vite 搭建组件库调试环境

vite 只在开发环境中使用,所以需要在安装时加上 -d

pnpm i vite@"3.0.7" -D

测试vite 是否安装成功

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <h1>Hello Component Vite</h1>
</body>
</html>

使用 npx 启用 vite 「npx 是Npm5.2新增的命令,用于执行软件包中的可执行文件」 npx vite

截屏2023-03-03 下午3.20.12.png

package.json 中添加启动脚本 运行环境直接使用 pnpm dev 就可以启动Vite 开发了

"scripts": { 
    "dev": "vite" 
}

小试牛刀-开发vue组件 —— Button

安装vue3.0

pnpm i vue@"3.2.37"

创建组件文件

src/button/VButton.ts 
import { defineComponent,h} from 'vue' 
export default defineComponent({ 
    name:'VButton', 
    render(){ 
        return h('button',null,'VButton') 
    } 
})

创建Vue实例

src/index.ts 
import { createApp } from "vue"; 
import VButton from "./button/VButton"; 
createApp(VButton).mount("#app");

index.html 增加容器 <div id="app"></div>

引入组件的script的标签记得增加 「script 标签中增加 type="module" 」否则不会展示

执行 pnpm dev

截屏2023-03-03 下午4.26.00.png

使用template模板开发组件

因为vue3.0中编译默认是在构建阶段进行编译完成的,是不支持模板编译功能,所以不可以直接放到浏览器直接运行,那么问题来了,让Vite可以编译Vue模板该怎么办呢?我们可以安装插件。

// vitejs/plugin-vue 
pnpm i @vitejs/plugin-vue@"3.0.3" -D

创建 /vite.config.ts

import { defineConfig } from "vite"; 
import vue from "@vitejs/plugin-vue"; 

export default defineConfig({ 
    plugins: [vue()]
});

下面我们就可以使用template 进行开发组件了

src/button/SFCButton.vue

 <template> 
     <button>SFC template</button> 
 </template>
 
 <script> 
     export default { name: "SFCButton", }; 
 </script>

引入到 src/index.ts 中测试下

// 支持vue template 模板

import SFCButton from './button/SFCButton.vue' 
createApp(SFCButton).mount('#app')

引入后你就会发现有红色的警告了 找不到模块./button/SFCButton.vue或其相应的类型声明。这是为Typescript 默认是不支持 .vue 类型模块,那么我们就需要添加一个模块类型来定义解决这个问题。

src/shims-vue.d.ts

declare module "*.vue" { 、
    import { DefineComponent } from "vue"; 
    const component: DefineComponent<{}, {}, any>;
    export default component; 
}

现在发现 红色的消失了,然后运行一下

截屏2023-03-03 下午5.54.04.png

使用JSX语法封装组件

想要支持jsx语法呢 就需要安装转译工具 vitejs/plugin-vue-jsx

pnpm i @vitejs/plugin-vue-jsx@"2.0.0" -D

/vite.config.ts

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

下面我们就可以使用jsx/tsx语法 进行开发组件了 /src/JSXButton.tsx

import { defineComponent,h } from 'vue';
export default defineComponent({
    name:"JSXButton",
    render(){
        return <button>JSXButton</button>
    }
})

如果使用的的vscode编译器,在ts中使用 JSX 语法编辑器会提示错误 配置下tsconfig ./tsconfig.json

{
    "compilerOptions": {
        "declaration": true, /* 生成相关的 '.d.ts' 文件。 */
        "declarationDir": "./dist/types", /* '.d.ts' 文件输出目录 */
        "jsx": "preserve",
    },
    "include": [
        "./**/*.*",
        "./shims-vue.d.ts",
    ],
    "exclude": [
        "node_modules"
    ],
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": "true"
}

组件全部引入与按需引入

一个组件库需要满意两种需求,1.全部引入,是以插件的形式引入全部组件。2.按照需求,引入自己想要的组件使用 Vue.component 注册。那么我们需要在入口文件实现两个功能1.导出全部组件;2.实现一个 Vue 插件,插件中编写 install 方法,将所有组件安装到 vue 实例中。

import { App } from "vue";
import VButton from "./VButton";
import SFCButton from "./button/SFCButton.vue";
import JSXButton from "./button/JSXButton";

// 单独导出
export { VButton, SFCButton, JSXButton };

// 实现install方法

export default {
  install(app: App): void {
    app.component(VButton.name, VButton);
    app.component(SFCButton.name, SFCButton);
    app.component(JSXButton.name, JSXButton);
  },
};

默认 Vite 就是可以支持构建,使用 Vite 的 build 命令就可以打包输出。如果导出的是一个库文件的话,还需要配置 导出模块类型 并确定导出的文件名

// 配置导出模块类型 并确定导出文件名
const rollupOptions = {
  external: ["vue", "vue-router"],
  output: {
    globals: {
      vue: "Vue",
    },
  },
};

export default defineConfig({
  ......
  
  build: {
    //添加库模式配置
    rollupOptions,
    minify: false,
    lib: {
      entry: "./src/entry.ts",
      name: "CompontentUI", // 注意不能使用中划线
      fileName: "Compontent-UI",
      // 导出模块格式
      formats: ["es", "umd", "iife"],
    },
  },
});

执行 vite build 就可以进行打包了 也可以在packjson中添加一个运行脚本

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

看到提示信息,证明打包成功了,就可以引入进行测试了。

截屏2023-03-11 下午5.55.26.png

创建demo文件 引入全部组件 使用 Vue.use 以 Vue 插件的形式引入 /demo/button/all.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <h1>Demo</h1>
    <div id="app"></div>
    <script type="module">
    import { createApp } from "vue/dist/vue.esm-bundler.js";
      import CompontentUI, {
        SFCButton,
        JSXButton,
        SButton,
      } from "../../dist/Compontent-UI.mjs";
      createApp({
        template: `
      <SButton/>
      <JSXButton/>
      <SFCButton/>
    `,
      })
        .use(CompontentUI)
        .mount("#app");
    </script>
  </body>
</html>

启动项目 pnpm dev 找到项目的路径 http://127.0.0.1:5173/demo/button/all.html

截屏2023-03-11 下午6.01.22.png

按需加载组件,使用 Vue.component 单个进行注册 /demo/button/index.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <h1>Demo2</h1>
    <div id="app"></div>
    <script type="module">
    import { createApp } from "vue/dist/vue.esm-bundler.js";
      import CompontentUI, {
        SFCButton,
        JSXButton,
        VButton,
      } from "../../dist/Compontent-UI.mjs";
      createApp({
        template: `
      <VButton/>
      <JSXButton/>
      <SFCButton/>
    `,
      })
        .component(VButton.name,VButton)
        .component(JSXButton.name,JSXButton)
        .component(SFCButton.name,SFCButton)
        .mount("#app");
    </script>
  </body>
</html>

截屏2023-03-11 下午6.09.00.png

这样我就使用vite 实现了一个小小的 Button 组件。

总结

  • 我们使用 Vite 从零搭建了 Vue 开发环境;

  • 配置插件 vitejs/plugin-vue 支持了SFC模板开发,添加添加一个模块的类型定义解决了.vue文件红色警告的问题;

  • 配置插件 vitejs/plugin-vue-jsx 支持了JSX语法开发,在 tsconfig 中配置一下 jsx 语法支持解决使用jsx/tsx文件报红问题

  • 组件库的封装 导出的两种形式全部导出,和单个导出;