前端脚手架开发流程

发布流程

  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

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

相关推荐
golang学习记4 小时前
从0死磕全栈之使用 VS Code 调试 Next.js 应用完整指南
前端
Mintopia4 小时前
🧩 隐私计算技术在 Web AIGC 数据处理中的应用实践
前端·javascript·aigc
尘世中一位迷途小书童4 小时前
代码质量保障:ESLint + Prettier + Stylelint 三剑客完美配置
前端·架构
Mintopia4 小时前
🧭 Next.js 架构与运维:当现代前端拥有了“分布式的灵魂”
前端·javascript·全栈
尘世中一位迷途小书童4 小时前
从零搭建:pnpm + Turborepo 项目架构实战(含完整代码)
前端·架构
JarvanMo4 小时前
Flutter 中的 ClipRRect | 每日 Flutter 组件
前端
某柚啊4 小时前
iOS移动端H5键盘弹出时页面布局异常和滚动解决方案
前端·javascript·css·ios·html5
心.c4 小时前
如何学习Lodash源码?
前端·javascript·学习
JamSlade4 小时前
react 无限画布难点和实现
前端·react.js