重构Action-cli前端脚手架

一、概述

最近一年,为了满足公司业务开发,解决重复搭建项目繁琐过程,自己开发了一个前端脚手架,并发布到npm。随着时间的推移,发现之前的版本存在很多问题,有些功能做不到位,而且代码也不是很规范,流程逻辑混乱等等。因此,为解决这些问题,我决定对其进行重构,添加检查更新版本功能,优化打包,将多个文件打包成单个cjs文件,支持更多的自定义以及快速克隆运行。

如果之前对这个项目没有了解的同学,可以去看上一篇关于脚手架开发的文章。

实现一个自定义前端脚手架_前端自定义脚手架-CSDN博客

二、实践

2.1、设计思路

  1. 提供命令行交互界面方便用户输入信息。
  2. 根据用户输入的信息从远端Git仓库拉取项目模板初始化项目。
  3. 发布到NPM,以便团队成员共享使用。
  4. 命令设计如下表2-1所示。

|----------------------------------------|----------|------------------------------------------|----------------------------|
| 命令 | 描述 | 选项 | 描述 |
| create <project-name> | 初始化项目 | -f,--force | 如果project-name已经存在,是否强制覆盖。 |
| create <project-name> | 初始化项目 | -t, --template [template-name] | 制定模板或git仓库链接 |
| create <project-name> | 初始化项目 | -r, --run | 克隆项目后是否自动运行 |
| create <project-name> | 初始化项目 | -c, --command [command] | 在自动运行模式,自定义运行命令 |
| create <project-name> | 初始化项目 | -pm, --packageManager [packageManager] | 指定包管理器 |
| create <project-name> | 初始化项目 | -b, --branch [branch-name] | 指定克隆分支 |
| list | 显示所有模板 | - | - |
| add <template-name> <template-url> | 新增模板配置 | - | - |
| remove <template-name> | 删除模板配置 | - | - |
| update | 更新脚手架 | - | - |
| ui | 界面操作 | -p, --port [port] | 指定端口 (number) |
| ui | 界面操作 | -h, --host [host] | 指定主机名称 (string) |
| - | - | -V,--version | 显示版本号 |
| - | - | -h,--help | 显示可用的CLI选项 |
| help [command] | 显示命令帮助信息 | --help | 显示命令帮助信息 |
[表2-1 命令设计]

2.2、初始化项目

项目初始化可以去看之前的文章,这里不再赘述。

实现一个自定义前端脚手架_前端自定义脚手架-CSDN博客

脚手架运行入口文件改为bin目录下,并在这里指定nodejs运行环境(#! /usr/bin/env node)

javascript 复制代码
// ./bin/index.js
#! /usr/bin/env node
require('../dist/index.js')

开新分支,从主分支开出v1.0.7和dev分支,分别用于保存之前版本的代码和现在开发的分支代码,最后会将dev分支合并到主分支。

2.3、配置Rollup打包

安装依赖

bash 复制代码
pnpm add rollup @rollup/plugin-node-resolve @rollup/plugin-commonjs rollup-plugin-node-externals@5  @rollup/plugin-json @rollup/plugin-terser rollup-plugin-typescript2 rollup-plugin-copy --save-dev

修改./package.json

javascript 复制代码
"scripts": {
    "build": "rollup -c rollup.config.js --bundleConfigAsCjs",
    // ...
}

新建rollup.config.js并配置

javascript 复制代码
import { defineConfig } from "rollup";
import nodeResolve from "@rollup/plugin-node-resolve";
import commonjs from "@rollup/plugin-commonjs";
import externals from "rollup-plugin-node-externals";
import json from "@rollup/plugin-json";
import terser from "@rollup/plugin-terser";
import typescript from "rollup-plugin-typescript2";
import copy from "rollup-plugin-copy";

export default defineConfig([
  {
    input: {
      index: "src/index.ts",
    },
    output: [
      {
        dir: "dist",
        format: "cjs",
      },
    ],
    plugins: [
      nodeResolve(),
      externals({
        devDeps: false, // 可以识别我们 package.json 中的依赖当作外部依赖处理 不会直接将其中引用的方法打包出来
      }),
      typescript(),
      json(),
      commonjs(),
      terser(),
      copy({
        targets: [
          {
            src: "src/templates.json", // 源路径
            dest: "dist", // 目标路径
          }, // 复制 templates.json 到 dist 目录下
        ],
        copyOnce: true, // 只复制一次
      }),
    ],
  },
]);

改造完成的项目结构

运行打包报错

2.4、解决打包错误

解决问题的思路:

第一种,直接复制报错信息到浏览器搜索相关解决文章。

第二中,就是根据报错信息,去github找到报错包相关issue,里面可能会有一些同学有同样的错误经历,可以参考他们如何解决。

错误:Cannot use import statement outside a module

解决:复制错误到浏览器搜索,【解决 SyntaxError: Cannot use import statement outside a module 报错问题】-CSDN博客

bash 复制代码
// ./package.json 
{ 
    // 新增 
    "type":"module" 
}

错误:[!] (plugin rpt2) RollupError: [plugin rpt2] Incompatible tsconfig option. Module resolves to 'CommonJS'. This is incompatible with Rollup, please use 'module: "ES2015"', 'module: "ES2020"', 'module: "ES2022"', or 'module: "ESNext"'.

解决:

bash 复制代码
// tsconfig.json 
{ "compilerOptions": { "module": "ESNext", }, }

错误:不能读取json文件

解决:

bash 复制代码
// tsconfig.json 
{
    "compilerOptions": {
        // ... 
        "resolveJsonModule": true,
    },
}

错误:[!] (plugin rpt2) RollupError: [plugin rpt2] error TS5070: Option '--resolveJsonModule' cannot be specified when 'moduleResolution' is set to 'classic'.

解决:

bash 复制代码
{
    "compilerOptions": {
        // ... 
        "moduleResolution": "node",
        "resolveJsonModule": true,
        "esModuleInterop": true,
    },
}

错误:[!] (plugin rpt2) RollupError: [plugin rpt2] src/commands/create/index.ts:11:16 - error TS2354: This syntax requires an imported helper but module 'tslib' cannot be found.

解决:

This syntax requires an imported helper but module 'tslib' cannot be found-CSDN博客

bash 复制代码
pnpm i tslib -D
bash 复制代码
// tsconfig.ts

{
    "compilerOptions": { 
        // ... 
        "paths": {
            "tslib": [
                "node_modules/tslib/tslib.d.ts"
            ]
        },
    },
}

npm run build成功打包

打包后运行node ./dist/index.js

报错:

解决:删除package.json中的"type":"module"即可。

项目根目录下打开命令行窗口,运行测试。

2.5、发布npm包

  1. 编写README.md

在README.md编写我们npm包的相关使用说明。

使用Static Badge | Shields.io生成专属图标,选择md格式就可以复制到README.md文档。

  1. 设置npm源

因为要把开发的脚手架上传到npm,需要把镜像源改回npm官方源,上传npm后再改回镜像源即可。

https://registry.npmmirror.com

bash 复制代码
# 查看
npm config get registry
# 设置npm官方源
npm config set registry https://registry.npmjs.org/
  1. 登录npm
bash 复制代码
npm login

按enter建,打开浏览器

输入账号密码登录

验证

登录成功

  1. 修改npm版本

重新发包,需要修改package.json里面version版本

bash 复制代码
# 打补丁,增加第三位(0.0.x)
npm version patch
# 添加功能,增加第二为位(0.x.0)
npm version minor
# 大版本更新,增加第一为位(x.0.0)
npm version major

需要先提交git后才能修改版本好号

  1. 发布npm
bash 复制代码
npm publish

发包报错,把package.json里的private改为false或删掉,再打包发布就可以了

打包发布

一直卡在publishing这里

修复package.json配置错误,去掉上图的警告

bash 复制代码
npm pkg fix

一直卡再正在发包,直到请求超时报错,因为网络可能存在代理的原因,检查电脑是否开启代理,反复开关代理测试发包,最后也是通过DevSiderCar开启npm加速才能成功重新发包。

登录npm官网就能看到刚刚发的包

action-cli - npmhttps://www.npmjs.com/package/action-cli

2.6、代码仓库

具体实现过程和使用,大家可以参考我的GitHub仓库地址。GitHub - Topskys/action-cli: 【前端脚手架】研究和着手搭建前端项目脚手架 https://www.npmjs.com/package/action-cli【前端脚手架】研究和着手搭建前端项目脚手架 https://www.npmjs.com/package/action-cli - Topskys/action-clihttps://github.com/Topskys/action-cli.git

三、效果

新版本help界面效果与之前版本多了update命令

创建项目,不带任何参数

查看所有模板文件

新增模板文件

删除模板文件,更新脚手架

从npm远程下载安装脚手架

bash 复制代码
npm install -g action-cli

指定参数创建项目,demo 为项目名称,-f 强制覆盖,-t 指定模板(模板名称或仓库地址),-r 下载项目后自动运行,-c 自定义运行shell脚本,-b 指定克隆的分支,-pm 指定包管理器。

脚手架成功创建项目,并打开浏览器运行项目。

四、参考文献

实现一个自定义前端脚手架_前端自定义脚手架-CSDN博客

【前端脚手架】实现一个自己的脚手架

【手把手教你实现前端脚手架】

【解决 SyntaxError: Cannot use import statement outside a module 报错问题】-CSDN博客

This syntax requires an imported helper but module 'tslib' cannot be found-CSDN博客

相关推荐
腾讯TNTWeb前端团队4 小时前
helux v5 发布了,像pinia一样优雅地管理你的react状态吧
前端·javascript·react.js
范文杰7 小时前
AI 时代如何更高效开发前端组件?21st.dev 给了一种答案
前端·ai编程
拉不动的猪7 小时前
刷刷题50(常见的js数据通信与渲染问题)
前端·javascript·面试
拉不动的猪7 小时前
JS多线程Webworks中的几种实战场景演示
前端·javascript·面试
FreeCultureBoy8 小时前
macOS 命令行 原生挂载 webdav 方法
前端
uhakadotcom8 小时前
Astro 框架:快速构建内容驱动型网站的利器
前端·javascript·面试
uhakadotcom9 小时前
了解Nest.js和Next.js:如何选择合适的框架
前端·javascript·面试
uhakadotcom9 小时前
React与Next.js:基础知识及应用场景
前端·面试·github
uhakadotcom9 小时前
Remix 框架:性能与易用性的完美结合
前端·javascript·面试
uhakadotcom9 小时前
Node.js 包管理器:npm vs pnpm
前端·javascript·面试