惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

SecWiki News
SecWiki News
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
V
Visual Studio Blog
博客园 - 叶小钗
S
SegmentFault 最新的问题
IT之家
IT之家
大猫的无限游戏
大猫的无限游戏
博客园_首页
Apple Machine Learning Research
Apple Machine Learning Research
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
月光博客
月光博客
酷 壳 – CoolShell
酷 壳 – CoolShell
腾讯CDC
D
Darknet – Hacking Tools, Hacker News & Cyber Security
V
V2EX
阮一峰的网络日志
阮一峰的网络日志
L
Lohrmann on Cybersecurity
量子位
C
Cyber Attacks, Cyber Crime and Cyber Security
T
Tor Project blog
J
Java Code Geeks
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
博客园 - 三生石上(FineUI控件)
Attack and Defense Labs
Attack and Defense Labs
AI
AI
The Cloudflare Blog
T
Tailwind CSS Blog
S
Schneier on Security
爱范儿
爱范儿
PCI Perspectives
PCI Perspectives
Stack Overflow Blog
Stack Overflow Blog
S
Secure Thoughts
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
T
The Exploit Database - CXSecurity.com
博客园 - 【当耐特】
V2EX - 技术
V2EX - 技术
S
Securelist
P
Proofpoint News Feed
T
Threat Research - Cisco Blogs
Help Net Security
Help Net Security
C
Cisco Blogs
N
News and Events Feed by Topic
人人都是产品经理
人人都是产品经理
B
Blog RSS Feed
K
Kaspersky official blog
T
The Blog of Author Tim Ferriss
G
Google Developers Blog
S
Security Affairs
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Simon Willison's Weblog
Simon Willison's Weblog

Leon.D’s Blog

使用Element.animate添加文字与图片动画 Howdz起始页开发记录 利用G渲染器实现的音频可视化方案 Vue3实现自定义右键菜单 Dashboard自定义面板项目介绍 开发Online Code Editor过程的一些记录 使用D3.js将离散的点形成平滑曲线及其应用 使用Taro-next将个人网盘功能扩展到微信小程序 Vue3上手, 使用vite实现一个简单的Todolist应用 断点续传与个人网盘系统的前后端设计 个人组件库展示站点搭建总结 Github Webhooks与Koa2实现简单的前端自动化部署 浏览器导航首页设计 CSS实现判断鼠标进入方向 简易电商系统开发记录(Nuxtjs+Koa) 考试系统设计总结
Howdyjs组件库迁移Vue3设计与总结
2021-01-30 · via Leon.D’s Blog

将个人组件库 Howdyjs 使用 Vue + Typescript 进行重构,使用 Vite 构建开发站点,Rollup 进行组件打包并分包发布 NPM。

主要变更

  1. 新版全面采用Typescript
  2. Vue 组件部分将使用Vue3重构,不向下兼容,有 Vue2.X 需求的请使用旧版
  3. 因各组件内的关联性不强,新版的组件库将进行分包发布,可便于按需加载
  4. 旧版多数包都将功能封装成 Vue 指令,并默认导出的是 Vue 指令,现在新版将默认导出原生构造函数,便于跨框架或原生使用,但同时保留了 Vue 指令封装的使用方式
  5. 使用lerna进行分包管理
  6. 使用Rollup进行组件打包
  7. 展示站点使用Vite搭建

架构说明

Vite

综合对比之后,发现采用 Vite 基本可以实现当前展示站点的所有功能,而且在开发环境下热更新速度极快,所以新版项目采用了 Vite 构建开发站点。

由于项目有导入.md 文件的需求,而 Vite 并不能直接使用 Webpack 的 markdown-loader,所以暂时自己写一个简单的 markdown-plugin 在 Vite 中使用

// vite.config.ts
const markdownPlugin = (options: any) => {
  return {
    name: "markdown",
    transform(code: string, id: string) {
      if (!/\.md/.test(id)) {
        return;
      }
      const result = marked(code, options);
      return `export default ${JSON.stringify(result)}`;
    },
  };
};
export default {
  plugins: [
    vue(),
    markdownPlugin({
      highlight: (code: string) => {
        if (code.includes("template")) {
          return hljs.highlight("html", code).value;
        } else if (code.includes('lang="ts"')) {
          return hljs.highlight("typescript", code).value;
        } else {
          return hljs.highlightAuto(code).value;
        }
      },
    }),
  ],
};

Vite 新版文档地址: https://vitejs.dev/

Lerna

Lerna 是一个项目内包管理工具,虽然当前项目内的组件关联性不强,但也提前先引入了 Lerna 进行分包管理。

  • 执行npm run bootstrap命令进行项目初始化.
  • 执行npm run publish命令可快速发包

Rollup 打包

组件使用 Rollup 进行打包,执行npm run build:pkg打包各 Packages,包含 cjs、es 和其 d.ts 文件。

使用 nodejs 执行 rollup 打包,代码位于/scripts 下,build.js 为打包初始模板,一个组件会被打包出 3 种格式:cjs/esm/umd,格式说明参考格式

Vue 路由自动生成

使用 Vite 打包时,Vue 路由懒加载是基于 Rollup 的动态引入插件的,它对我原站点的格式不太适用。而由于展示站点中,各个路由格式是具有一定通用性的,所有采用了一种读取文件目录自动生成路由文件的方式。

// scripts/gen-route.js
// 自动生成路由文件
const fs = require("fs");
const packagesDirs = fs.readdirSync("./src/pages");
const packagesMap = {};
packagesDirs.map((package) => {
  const exampleDirs = fs.readdirSync(`./src/pages/${package}/example`);
  const exampleNum = exampleDirs.length;
  packagesMap[package] = exampleNum;
});
const packages = Object.keys(packagesMap).map((key) => {
  return {
    name: key,
    exampleNum: packagesMap[key],
  };
});
const routes = [
  {
    path: "/",
    name: "home",
    component: "i(../views/home.vue)",
  },
  ...packages.map((pkg) => {
    const { name, exampleNum } = pkg;
    return {
      path: `/${name}`,
      name: `${name}`,
      redirect: `/${name}/readme`,
      component: `i(../pages/${name}/index.vue)`,
      children: [
        {
          path: `/${name}/readme`,
          name: `${name}-readme`,
          component: "i(../components/PageReadme.vue)",
        },
        ...Array.from({ length: exampleNum }, (_, exampleIndex) => {
          return {
            path: `/${name}/example${exampleIndex + 1}`,
            name: `${name}-example${exampleIndex + 1}`,
            component: `i(../pages/${name}/example/example${
              exampleIndex + 1
            }.vue)`,
          };
        }),
      ],
    };
  }),
];

const reg = /"i\((.*?)\)"/g;
const routesStr = JSON.stringify(routes, null, 2).replace(
  reg,
  (...arg) => `() => import("${arg[1]}")`
);

const output = `
/* eslint-disable */
import { createRouter, createWebHistory } from 'vue-router';
const router = createRouter({
  history: createWebHistory('/howdy/'),
  routes: ${routesStr}
});

export default router;
`;

fs.writeFileSync("./src/router/index.ts", output);

执行命令npm run gen-router后,会自动读取/packages 下的包文件,然后生成出对应的路由。

说明