一、概述
最近一年,为了满足公司业务开发,解决重复搭建项目繁琐过程,自己开发了一个前端脚手架,并发布到npm。随着时间的推移,发现之前的版本存在很多问题,有些功能做不到位,而且代码也不是很规范,流程逻辑混乱等等。因此,为解决这些问题,我决定对其进行重构,添加检查更新版本功能,优化打包,将多个文件打包成单个cjs文件,支持更多的自定义以及快速克隆运行。
如果之前对这个项目没有了解的同学,可以去看上一篇关于脚手架开发的文章。
二、实践
2.1、设计思路
- 提供命令行交互界面方便用户输入信息。
- 根据用户输入的信息从远端Git仓库拉取项目模板初始化项目。
- 发布到NPM,以便团队成员共享使用。
- 命令设计如下表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、初始化项目
项目初始化可以去看之前的文章,这里不再赘述。
脚手架运行入口文件改为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包
在README.md编写我们npm包的相关使用说明。
使用Static Badge | Shields.io生成专属图标,选择md格式就可以复制到README.md文档。
- 设置npm源
因为要把开发的脚手架上传到npm,需要把镜像源改回npm官方源,上传npm后再改回镜像源即可。
https://registry.npmmirror.com
bash
# 查看
npm config get registry
# 设置npm官方源
npm config set registry https://registry.npmjs.org/
- 登录npm
bash
npm login
按enter建,打开浏览器
输入账号密码登录
验证
登录成功
- 修改npm版本
重新发包,需要修改package.json里面version版本
bash
# 打补丁,增加第三位(0.0.x)
npm version patch
# 添加功能,增加第二为位(0.x.0)
npm version minor
# 大版本更新,增加第一为位(x.0.0)
npm version major
需要先提交git后才能修改版本好号
- 发布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 指定包管理器。
脚手架成功创建项目,并打开浏览器运行项目。
四、参考文献
【解决 SyntaxError: Cannot use import statement outside a module 报错问题】-CSDN博客
This syntax requires an imported helper but module 'tslib' cannot be found-CSDN博客