Howdyjs is an open source JS plug-in tool library. The old version encapsulates some Vue instructions and common components. Now part of the Vue instructions are extracted and implemented using native JS, while the Vue components are reconstructed using Vue3 and the Document presentation site is reconstructed using Vite. This article documents instructions for refactoring development.

🔗 Link

  • âš¡ making
  • 📖 Document
  • 💾 NPM

🌟 Major changes

  1. New full adoptionTypescript
  2. Vue component parts will be usedVue3Reconfiguration, not backward compatible, please use the old version of Vue2.X requirements
  3. Due to the weak correlation between components, the new component library will be distributed as a subcontract, which can be easily loaded on demand
  4. While most packages in the old version encapsulated functions as Vue directives and exported them by default, the new version now exports native constructors by default, making it easier to use them across frameworks or native, while retaining the use of Vue directives wrapped
  5. uselernaManage subcontracting
  6. useRollupPackage components
  7. Show site usageViteSet up

🚀 currently contains plug-ins

  1. @howdyjs/resizeChange element size by drag and drop plug-in
  2. @howdyjs/img-zoomImage magnifying plug-in, support to view the next picture by group
  3. @howdyjs/size-observerPlugins that listen for element size changes
  4. @howdyjs/scrollCustom scroll bar plug-in
  5. @howdyjs/to-dragSet up the Dom draggable plug-in
  6. @howdyjs/animation-dialogAnimated modal box Vue3 component
  7. @howdyjs/standard-tabsVue3 component of the mobile TAB
  8. @howdyjs/mouse-menuCustom right-click menu Vue3 components
  9. @howdyjs/to-controlDrag and drop to change element size and position plug-in

🌈 Project architecture description

Vite

After comprehensive comparison, it is found that Vite can basically achieve all the functions of the current display site, and the hot update speed is very fast in the development environment, so the new version of the project uses Vite to build the development site.

Since the project has the requirement to import. Md files, and Vite cannot directly use Webpack markdown-loader, so I temporarily write a simple Markdown-plugin to use in Vite (the latest and mature official plugin has been provided).

// 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 The ${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 {
          returnhljs.highlightAuto(code).value; }}})]}Copy the code

Vite document address :vitejs.dev/

Lerna

Lerna is a project multi-package management tool. Although the components in the current project are not highly correlated, Lerna has been introduced in advance for subcontracting management.

  • performnpm run bootstrapCommand to initialize the project.
  • performnpm run publishCommands can send packets quickly

Lerna- How to gracefully manage multiple NPM packages – Zhihu (zhihu.com)

A Rollup packaging

Components in the component library are finally packaged using Rollup. NPM Run Build: PKG Packages are packaged, including CJS, ES and their D.ts files.

The rollup package is performed using nodeJS, the code is located in the scripts directory, build.js is the initial package template, and a component is packaged in three formats: CJS/ESM/UMD.

Type files use the native typescript declaration to generate D.ts files

Packages directory will be automatically read when packaging, packaging each grid file.

Automatically generate display site Vue routes

When using Vite packaging, the Vue route lazy loading is dynamically introduced based on Rollup plug-in, which is not suitable for the format of my original site. In the display site, each routing format has a certain universality, so a way of automatically generating routing files by reading file directory is adopted. In Vite, Glob imports are provided to read file directories.

// src/router/index.ts
import { createRouter, createWebHashHistory, createWebHistory } from 'vue-router';
const isHashRouterMode = import.meta.env.VITE_ROUTER_MODE === 'hash';
const packageMain = import.meta.glob('.. /pages/*/index.vue');
const exampleMain = import.meta.glob('.. /pages/*/example/*.vue');
const packageMainMap: Record<string.any> = {};
Object.keys(packageMain).map(key= > {
  const reg = /^.*pages/(.*)/index.*$/;
  const pkg = key.replace(reg, (. args) = > args[1]);
  packageMainMap[pkg] = packageMain[key];
});
const router = createRouter({
  history: isHashRouterMode ? createWebHashHistory() : createWebHistory('/howdy/'),
  routes: [{path: '/'.name: 'home'.component: () = > import('.. /views/home.vue')},... Object.keys(packageMainMap).map(pkg= > {
      const examples = Object.keys(exampleMain).filter(p= > p.includes(pkg));
      return {
        path: ` /${pkg}`.name: `${pkg}`.redirect: ` /${pkg}/readme`.component: packageMainMap[pkg],
        children: [{path: ` /${pkg}/readme`.name: `${pkg}-readme`.component: () = > import('.. /components/PageReadme.vue')},... examples.map((example,index) = > {
            return {
              path: ` /${pkg}/example${index + 1}`.name: `${pkg}-example${index + 1}`.component: exampleMain[example] }; }})]; ]}}));export default router;
Copy the code

Display Vue file source code to the page

The display site displays the Vue source code files for each Example on the page, with highlightJS to highlight the code.

After scrolling through the official documentation, Vite writes? Raw can read code sources directly out of strings, similar to the Raw-loader feature in WebPack. However, after redeveloping the package deployment, it was found that there was a read failure, and finally it was found that there was a rollup dynamic import problem.

Related ISSUES: Click here

Finally, temporarily convert the associated Vue files directly into Markdown files when the development is started or packaged. Execute NPM Run VUe-to-MD in the project for the transformation. The relevant code is very simple, but this way to implement hot update is too cumbersome, we will see how to use a more appropriate solution.

const fs = require('fs');
const glob = require('glob');
const classifys = fs.readdirSync('src/pages');
classifys.map(classify= > {
  fs.mkdirSync(`src/code/${classify}`, { recursive: true });
});
glob('src/pages/**/example/example*.vue'.(err, files) = > {
  if (err) {
    throw err;
  }
  files.map(file= > {
    const codeFileName = file.replace('pages'.'code').replace('example/'.' ').replace('vue'.'md');
    const code = fs.readFileSync(file, 'utf8');
    const output = `\`\`\`vue\n${code}\ ` \ ` \ ` `;
    fs.writeFileSync(codeFileName, output);
  });
});
Copy the code

âš¡ Other Instructions

  • New address :Howdyjs
  • Howdyjs-old (compatible with Vue2, currently not maintained)
  • We use the same Github repository, the new version refers to the Master branch, the old version refers to the Howdy branch
  • Welcome Star, if you have questions or better idea, welcome Issue and PR.