Analyzing the Element‑Plus Vue3 Component Library: Architecture, TypeScript Integration, and Build Process
This article examines the Element‑Plus Vue3 component library, detailing its TypeScript refactor, Composition API usage, Teleport implementation, global‑instance API changes, internationalization support, and the multi‑tool build pipeline involving Rollup, Webpack, and Gulp.
Element‑Plus is a Vue3‑based component library rebuilt with TypeScript and the Composition API. This article examines its source code, highlighting major updates such as TypeScript development, Vue 3 Composition API, Teleport, global‑instance API, internationalization, and the multi‑tool build pipeline.
TypeScript Integration
Element‑Plus adopts TypeScript, ESLint rules, a tsconfig.json , and uses Rollup plugins ( @rollup/plugin-node-resolve , rollup-plugin-terser , rollup-plugin-typescript2 , rollup-plugin-vue ) to produce ES‑module bundles. The following Rollup configuration illustrates the setup:
// build/rollup.config.bundle.js
import { nodeResolve } from "@rollup/plugin-node-resolve";
import { terser } from "rollup-plugin-terser";
import typescript from "rollup-plugin-typescript2";
const vue = require("rollup-plugin-vue");
export default [
{
// ... 省略前面部分内容
plugins: [
terser(),
nodeResolve(),
vue({
target: "browser",
css: false,
exposeFilename: false,
}),
typescript({
tsconfigOverride: {
include: ["packages/**/*", "typings/vue-shim.d.ts"],
exclude: ["node_modules", "packages/**/__tests__/*"],
},
}),
],
},
];
复制代码;Type declaration files such as typings/vue-shim.d.ts provide global types and enable import X from X.vue with proper typing.
// typings/vue-shim.d.ts
declare module '*.vue' {
import { defineComponent } from 'vue'
const component: ReturnType
export default component
}
declare type Nullable
= T | null;
declare type CustomizedHTMLElement
= HTMLElement & T
declare type Indexable
= {
[key: string]: T
}
declare type Hash
= Indexable
declare type TimeoutHandle = ReturnType
declare type ComponentSize = 'large' | 'medium' | 'small' | 'mini'
复制代码;Composition API
Vue 3’s Composition API reduces coupling and simplifies logic. The library extracts reusable hooks under packages/hooks , for example the use-attrs hook that mirrors $attrs and $listener while filtering unnecessary properties.
watchEffect(() => {
const res = entries(instance.attrs).reduce((acm, [key, val]) => {
if (!allExcludeKeys.includes(key) && !(excludeListeners && LISTENER_PREFIX.test(key))) {
acm[key] = val;
}
return acm;
}, {});
attrs.value = res;
});
复制代码;Teleport Usage
Mount‑type components such as Dialog, Drawer, Tooltip and Popover use the new Teleport feature to render their markup in a specified DOM node, controlled by the append-to-body prop.
<template>
<teleport to="body" :disabled="!appendToBody">
<transition name="dialog-fade" @after-enter="afterEnter" @after-leave="afterLeave">
...
</transition>
</teleport>
</template>
复制代码;Global‑Instance API
In Vue 2 the library used global APIs ( Vue.component , Vue.use , Vue.prototype ). In Vue 3 these have been migrated to the application instance ( app ) with app.component and app.use . Message components are installed via app.use and expose global properties on app.config.globalProperties .
const install = (app: App, opt: InstallOptions): void => {
const option = Object.assign(defaultInstallOpt, opt)
use(option.locale)
app.config.globalProperties.$ELEMENT = option // 全局设置默认的size属性和z-index属性
// 全局注册所有除了plugins之外的组件
components.forEach(component => {
app.component(component.name, component)
})
plugins.forEach(plugin => {
app.use(plugin as any)
})
}
复制代码; (Message as any).install = (app: App): void => {
app.config.globalProperties.$message = Message
}
复制代码;Internationalization
The packages/locale folder defines t and use helpers to translate strings and switch the global language, delegating date handling to dayjs instead of moment.js .
export const t = (path: string, option?): string => {
let value;
const array = path.split(".");
let current = lang;
for (let i = 0, j = array.length; i < j; i++) {
const property = array[i];
value = current[property];
if (i === j - 1) return template(value, option);
if (!value) return "";
current = value;
}
return "";
};
复制代码; export const use = (l): void => {
lang = l || lang;
if (lang.name) {
dayjs.locale(lang.name);
}
};
复制代码;Website Packaging
The documentation site is built with Webpack, using vue-loader for .vue files, babel-loader for JS/TS, and a custom md-loader to extract <template> and <script> sections from markdown.
rules: [
{
test: /\.vue$/,
use: "vue-loader",
},
{
test: /\.(ts|js)x?$/,
exclude: /node_modules/,
loader: "babel-loader",
},
{
test: /\.md$/,
use: [
{
loader: "vue-loader",
options: { compilerOptions: { preserveWhitespace: false } },
},
{ loader: path.resolve(__dirname, "./md-loader/index.js") },
],
},
{
test: /\.(svg|otf|ttf|woff2?|eot|gif|png|jpe?g)(\?\S*)?$/,
loader: "url-loader",
query: {
limit: 10000,
name: path.posix.join("static", "[name].[hash:7].[ext]"),
},
},
];
复制代码;Component and Style Bundling
Both Rollup (ES‑module) and Webpack (UMD) are used to produce library bundles. Styles and fonts are packaged with Gulp, compiling SCSS to CSS and copying assets to lib/theme-chalk .
// packages/theme-chalk/gulpfile.js
function compile() {
return src("./src/*.scss")
.pipe(sass.sync())
.pipe(autoprefixer({ cascade: false }))
.pipe(cssmin())
.pipe(
rename(function (path) {
if (!noElPrefixFile.test(path.basename)) {
path.basename = `el-${path.basename}`;
}
})
)
.pipe(dest("./lib"));
}
function copyfont() {
return src("./src/fonts/**").pipe(cssmin()).pipe(dest("./lib/fonts"));
}
复制代码;Lerna Monorepo
Element‑Plus employs Lerna and Yarn workspaces to manage packages under packages/* , sharing dependencies at the root and enabling individual component publishing.
{
"name": "@element-plus/message",
"version": "0.0.0",
"main": "dist/index.js",
"license": "MIT",
"peerDependencies": { "vue": "^3.0.0" },
"devDependencies": { "@vue/test-utils": "^2.0.0-beta.3" }
}
复制代码; "workspaces": ["packages/*"]
复制代码;Conclusion
Reading the Element‑Plus source offers insight into modern component design, Vue 3 features, and multi‑tool build strategies, and contributors can submit pull requests to help the project evolve.
References
Rollup + TS library development guide – engineering setup
Quickly use Vue3’s 15 most common APIs
vue‑3‑playground repository
Vue3 official documentation – TypeScript support
Comparison of Vue3 Hooks and React Hooks
Sohu Tech Products
A knowledge-sharing platform for Sohu's technology products. As a leading Chinese internet brand with media, video, search, and gaming services and over 700 million users, Sohu continuously drives tech innovation and practice. We’ll share practical insights and tech news here.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.