开发vue组件库——学习element-plus打包(三)

132 阅读2分钟

rollup.js

rollupjs,熟悉vue的人都应该知道这个,和我们的vite大哥关系简直不要太好。
想要编译vue代码,那肯定少不了plugin,多年的搬砖经验,我发现element-plusvite插件来解析vue代码

安装rollup

在根目录下创建build文件夹,用来存放打包相关的代码。
然后在build目录下运行pnpm init,生成package.json

{
  "name": "@udesign-vue/build",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "start": ""
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
}

继续在build目录下安装相关依赖

  • rollup
  • fast-glob 用nodejs的文件搜索库,可能是最快的。
  • unplugin-vue-macros 可以使用vue新特性,这里主要用defineOptions
  • @vitejs/plugin-vue
  • @vitejs/plugin-vue-jsx
  • @rollup/plugin-node-resolverollup认识外部依赖。
  • @rollup/plugin-commonjs
  • rollup-plugin-esbuild 用esbuild来编译ts/esnext代码,这样你就不用安装typescript相关的插件了

在编写构建代码之前,我们要先定义好目录,这样后面用起来也方便。
创建build/src/utils/paths.ts

import { resolve } from "path";

export const projRoot = resolve(__dirname, "..", "..", ".."); // 根目录
export const pkgRoot = resolve(projRoot, "packages");
export const compRoot = resolve(pkgRoot, "components");

// 打包
export const outputRoot = resolve(projRoot, "dist");
export const pkgOutput = resolve(outputRoot, "udesign-vue");

开始写打包方法,首先创建build/src/tasks/buildComponent.ts

import { rollup } from "rollup";
import glob from "fast-glob";
import { pkgRoot } from "../utils/paths";
import VueMacros from "unplugin-vue-macros/vite";
import vue from "@vitejs/plugin-vue";
import vueJsx from "@vitejs/plugin-vue-jsx";
import nodeResolve from "@rollup/plugin-node-resolve";
import commonjs from "@rollup/plugin-commonjs";
import esbuild from "rollup-plugin-esbuild";
import { target, buildConfig } from "../config/build-info";

export const buildComponent = async () => {
  // 使用 fast-glob 查找packages/**符合指定条件的文件
  const input = await glob("**/*.{js,ts,vue}", {
    cwd: pkgRoot,
    absolute: true,
    onlyFiles: true,
    ignore: ["**/node_modules/**", "**/dist/**", "gulpfile.ts"],
  });

  const bundle = await rollup({
    input,
    plugins: [
      VueMacros({
        plugins: {
          vue: vue(),
          vueJsx: vueJsx(),
        },
      }),
      nodeResolve({
        extensions: [".mjs", ".js", ".json", ".ts"],
      }),
      commonjs(),
      esbuild({
        sourceMap: true,
        target,
        minify: false, // 压缩代码,建议生产环境开启
        // 当遇到.vue文件使用ts来处理
        loaders: {
          ".vue": "ts",
        },
      }),
    ],
    external: "vue",
  });

  Promise.all(buildConfig.map((option) => bundle.write(option)));
};

buildComponent();

创建build/src/config/build-info.ts用来存放打包的一些信息。

import { resolve } from "path";
import { pkgOutput, compRoot } from "../utils/paths";

export const target = "es2018";

import type { OutputOptions } from "rollup";

// rollup 输出配置
export const buildConfig: OutputOptions[] = [
  {
    format: "esm",
    dir: resolve(pkgOutput, "es"),
    preserveModules: true, // 保留模块目录结构
    preserveModulesRoot: compRoot, // 相对于设置的目录去生成打包目录
    sourcemap: true,
    entryFileNames: `[name].mjs`,
  },
  {
    format: "cjs",
    dir: resolve(pkgOutput, "lib"),
    exports: "named",
    preserveModules: true,
    preserveModulesRoot: compRoot,
    sourcemap: true,
    entryFileNames: `[name].js`,
  },
];

然后用Code Runner插件运行你就会得到打包后的产物dist

image.png

image.png