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

推荐订阅源

人人都是产品经理
人人都是产品经理
MyScale Blog
MyScale Blog
Y
Y Combinator Blog
罗磊的独立博客
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
P
Proofpoint News Feed
Google DeepMind News
Google DeepMind News
V
Vulnerabilities – Threatpost
T
The Blog of Author Tim Ferriss
云风的 BLOG
云风的 BLOG
Recorded Future
Recorded Future
N
News and Events Feed by Topic
B
Blog RSS Feed
阮一峰的网络日志
阮一峰的网络日志
博客园_首页
C
CXSECURITY Database RSS Feed - CXSecurity.com
博客园 - 【当耐特】
N
Netflix TechBlog - Medium
博客园 - 叶小钗
B
Blog
Vercel News
Vercel News
T
Tenable Blog
T
The Exploit Database - CXSecurity.com
Spread Privacy
Spread Privacy
T
Threat Research - Cisco Blogs
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Last Week in AI
Last Week in AI
F
Fortinet All Blogs
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
Microsoft Security Blog
Microsoft Security Blog
S
Securelist
Microsoft Azure Blog
Microsoft Azure Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
P
Palo Alto Networks Blog
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
D
DataBreaches.Net
Cyberwarzone
Cyberwarzone
Engineering at Meta
Engineering at Meta
Martin Fowler
Martin Fowler
G
GRAHAM CLULEY
Project Zero
Project Zero
Cisco Talos Blog
Cisco Talos Blog
A
Arctic Wolf
C
CERT Recently Published Vulnerability Notes
L
LangChain Blog
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
C
Check Point Blog
A
About on SuperTechFans
W
WeLiveSecurity
The GitHub Blog
The GitHub Blog

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 下的包文件,然后生成出对应的路由。

说明