前端脚手架开发流程

发布流程

  1. 创建一个 npm 项目
bash 复制代码
mkdir frame-start
cd frame-start
npm init -y
  1. 创建 bin 文件夹,并在文件夹中创建入口文件
js 复制代码
#!/usr/bin/env node
console.log('脚手架')
  1. 在 package.json 中指定入口文件
js 复制代码
{
  "name": "frame-start", 
  "version": "1.0.0-beta",
  "main": "index.js",
  "bin":{
    "frame-start":"bin/index.js"
  },
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "description": ""
}
  1. npm 发包
js 复制代码
npm login
npm publish

使用流程

  1. 全局安装脚手架
js 复制代码
npm i frame-start -g

此时可能会有一个报错,如下:

js 复制代码
npm error code EACCES
npm error syscall symlink
npm error path ../lib/node_modules/frame-start/bin/index.js
npm error dest /usr/local/bin/frame-start
npm error errno -13
npm error [Error: EACCES: permission denied, symlink '../lib/node_modules/frame-start/bin/index.js' -> '/usr/local/bin/frame-start'] {
npm error   errno: -13,
npm error   code: 'EACCES',
npm error   syscall: 'symlink',
npm error   path: '../lib/node_modules/frame-start/bin/index.js',
npm error   dest: '/usr/local/bin/frame-start'
npm error }
npm error
npm error The operation was rejected by your operating system.
npm error It is likely you do not have the permissions to access this file as the current user
npm error
npm error If you believe this might be a permissions issue, please double-check the
npm error permissions of the file and its containing directories, or try running
npm error the command again as root/Administrator.
npm error A complete log of this run can be found in: /Users/***/.npm/_logs/2025-10-19T08_25_04_472Z-debug-0.log

报错原因:

在执行 npm install -g frame-start 或类似全局安装命令时,npm 试图在 /usr/local/bin/ 目录下创建一个符号链接(symlink),但当前用户没有权限写入该目录。/usr/local/bin/ 是系统目录,普通用户默认没有写权限,所以会报 EACCES: permission denied 权限错误。

使用 sudo 提升权限执行安装命令

sql 复制代码
sudo npm install -g frame-start

系统会提示你输入密码,输入后即可完成安装。

  1. 测试脚手架,执行 frame-start
js 复制代码
~ % frame-start
脚手架
  1. 可以查询 frame-start 的安装路径
js 复制代码
~ % which frame-start
/usr/local/bin/frame-start

~ % ls -l /usr/local/bin/frame-start
lrwxr-xr-x  1 root  wheel  44 10 19 16:27 /usr/local/bin/frame-start -> ../lib/node_modules/frame-start/bin/index.js

本地调试脚手架

  1. 切换到当前开发目录下
js 复制代码
pwd
/Users/xxx/Desktop/study/frame-start
  1. 执行 npm link,这会把当前项目链接到全局 npm 模块:
bash 复制代码
sudo npm link

原理:利用了 npm 的全局符号链接机制 把本地项目"挂载"到全局 npm 模块和可执行命令目录,实现了本地项目的全局可执行化。

假设项目路径是 /Users/yourname/projects/frame-start

在项目根目录执行:

bash 复制代码
npm link

npm 会做两件事:

  1. 第一层链接(全局模块目录中的 frame-start):
  • 位置:/usr/local/lib/node_modules/frame-start
  • 指向:本地项目根目录 /Users/yourname/projects/frame-start
  • 作用:让 npm 把你的本地项目识别为一个 "已安装的全局模块"。这样 npm 可以读取项目的 package.json(比如其中的 bin 配置),为后续创建可执行命令铺路。
  1. 第二层链接(全局可执行目录中的 frame-start):
  • 位置:/usr/local/bin/frame-start
  • 指向:../lib/node_modules/frame-start/bin/index.js(即通过第一个链接找到本地项目的入口文件)
  • 作用:让终端能直接识别 frame-start 命令。因为 /usr/local/bin 是系统默认的 "可执行程序搜索目录",终端输入 frame-start 时,会自动在这里找到这个符号链接,并执行它指向的 bin/index.js(你的 CLI 入口代码)。

为什么需要两层链接?

  • 第一层链接(全局模块目录)的核心是 "让 npm 管理模块元信息"(比如读取 package.jsonbin 配置,知道命令对应的入口文件路径)。
  • 第二层链接(全局可执行目录)的核心是 "让系统能识别命令"(把 CLI 入口文件映射到系统可执行路径,实现终端直接调用)。

../lib/node_modules/frame-start 和 /usr/local/lib/node_modules/frame-start 是同一个目录,表示方式不同。

分包脚手架调试

假设你有两个包:

  • /path/to/frame-start-core
  • /path/to/frame-start-cli (依赖 core)
  1. 先在核心包目录执行:
js 复制代码
cd /path/to/frame-start-core
npm link
  1. 然后在 CLI 包目录执行:
bash 复制代码
cd /path/to/frame-start-cli
npm link frame-start-core

会把 CLI 包中的 frame-start-core 依赖指向你本地的核心包代码,实现本地联调。 3. 在 CLI 包目录执行:

js 复制代码
npm link

将 CLI 包链接到全局,方便执行命令调试。

  • 解除链接
    若后续需恢复依赖为 npm 仓库包,可执行:
js 复制代码
在 CLI 包目录执行 `npm unlink frame-start-core`(解除与本地核心包的关联);
在核心包目录执行 `npm unlink`(从本地全局移除核心包链接)。

脚手架命令注册和参数解析

命令注册

  1. 执行 frame-start init
  2. 在入口文件中获取命令
js 复制代码
const argv = require('process').argv
console.log(argv) // 'init'

参数解析

  1. 执行 frame-start init --name vue-demo
  2. 在入口文件中获取参数
js 复制代码
let [option, param] = argv.slice(3)
option = option.replace('--','')
console.log(option) // name
console.log(param) // vue-demo

参考:为什么本地调试脚手架时需要两次符号链接

相关推荐
ywf12151 小时前
前端的dist包放到后端springboot项目下一起打包
前端·spring boot·后端
恋猫de小郭1 小时前
2026,Android Compose 终于支持 Hot Reload 了,但是收费
android·前端·flutter
hpoenixf7 小时前
2026 年前端面试问什么
前端·面试
还是大剑师兰特7 小时前
Vue3 中的 defineExpose 完全指南
前端·javascript·vue.js
泯泷8 小时前
阶段一:从 0 看懂 JSVMP 架构,先在脑子里搭出一台最小 JSVM
前端·javascript·架构
mengchanmian8 小时前
前端node常用配置
前端
华洛9 小时前
利好打工人,openclaw不是企业提效工具,而是个人助理
前端·javascript·产品经理
xkxnq9 小时前
第六阶段:Vue生态高级整合与优化(第93天)Element Plus进阶:自定义主题(变量覆盖)+ 全局配置与组件按需加载优化
前端·javascript·vue.js
A黄俊辉A10 小时前
vue css中 :global的使用
前端·javascript·vue.js
小码哥_常10 小时前
被EdgeToEdge适配折磨疯了,谁懂!
前端