重构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博客

相关推荐
studyForMokey10 分钟前
[Kotlin标准函数] run、with、apply、also、let、use等
前端·python·kotlin
随·枫1 小时前
datalist 是什么?以及作用是什么?
前端
码农小丘1 小时前
第二章 Spring Boot快速⼊⻔ —— Spring Boot配置文件
java·前端·spring boot
yqcoder1 小时前
reactflow 中 selectionMode 组件作用
前端·javascript
伏飞而行1 小时前
七、利用CSS和多媒体美化页面的习题
前端·css·html5
GISer_Jing2 小时前
React面试高频核心问题
前端·react.js·面试
我不要放纵2 小时前
通过shell脚本分析部署nginx网络服务
前端·网络·chrome
Mrs_Lupin3 小时前
如何在react中使用react-monaco-editor渲染出一个编辑器
前端·react.js·编辑器
碎像3 小时前
Vue 中的透传,插槽,依赖注入
前端·javascript·vue.js
想你的风吹到了瑞士3 小时前
vue如何实现组件切换
前端·javascript·vue.js