必须前后端物理隔离:api/与web/平级,composer管php依赖,npm/yarn管前端资源;禁止混用或提交node_modules;CI/CD分步安装构建;开发时代理/api请求,配置正确base路径防404。

可以,但必须明确划分职责边界:Composer管PHP后端依赖,NPM/Yarn管前端资源(如构建工具、css框架、js库),两者不能互相替代,也不能混放同一目录。
为什么不能把 node_modules 提交到 git 或让 Composer 安装前端包
前端依赖体积大、平台相关(node_modules 里含二进制文件)、更新频繁,且 Composer 的 autoloader 不识别 JS/TS/CSS。强行用 Composer 安装前端包(如通过 composer/installers)会导致:
– 构建流程断裂(webpack/vite 找不到入口)
– vendor/ 膨胀到数百 MB
– CI/CD 构建时间翻倍
– 团队成员 npm install 失败却去查 composer.json
推荐的项目结构:前后端物理隔离
根目录下分设两个独立子目录,各自拥有完整生态:
my-project/ ├── api/ ← PHP 后端(含 composer.json) │ ├── src/ │ ├── vendor/ │ └── composer.json └── web/ ← 前端 SPA(含 package.json) ├── src/ ├── dist/ ← 构建输出,由 PHP 静态服务托管 ├── node_modules/ └── package.json
关键点:
– api/ 和 web/ 是平级目录,无嵌套关系
– web/dist/ 目录由前端构建生成,PHP 只负责将其作为静态资源提供(例如 nginx 的 root /path/to/my-project/web/dist;)
– API 接口统一走 /api/xxx,前端路由用 history 模式时需后端 fallback 到 index.html
立即学习“PHP免费学习笔记(深入)”;
CI/CD 中如何协调两套依赖安装与构建
在 github Actions / gitlab CI 等流程中,必须分步执行,且缓存策略要分开:
- 先
cd api && composer install --no-dev --optimize-autoloader - 再
cd web && npm ci && npm run build(或yarn install --frozen-lockfile && yarn build) - 缓存分别配置:
– Composer 缓存路径:~/.composer/cache
– NPM 缓存路径:~/.npm或web/node_modules(推荐后者,更稳定) - 注意 Node.js 和 PHP 版本需显式声明(如 GitHub Actions 中用
actions/setup-node和shivammathur/setup-php)
本地开发时如何避免端口冲突和跨域问题
不要让 PHP 内置服务器(php -S)直接 serve 前端代码;也不要用 Webpack Dev Server 代理所有请求到 PHP —— 这容易掩盖真实 CORS 配置问题。
正确做法:
– 前端用 npm run dev 启动 Vite/Webpack Dev Server(默认 http://localhost:5173)
– 后端用 php -S localhost:8000 -t public(仅响应 /api/ 路由)
– 在前端 vite.config.ts 中配代理:
export default defineConfig({ server: { proxy: { '/api': { target: 'http://localhost:8000', changeOrigin: true, rewrite: (path) => path.replace(/^/api/, '') } } } })
这样开发时前端发 GET /api/users 实际被代理到 http://localhost:8000/users,而生产环境则靠 Nginx 统一路由,无需改代码。
最常被忽略的一点:前端构建产物(dist/)的 HTML 中, 这类路径必须是相对 public root 的绝对路径,否则上线后 404 —— 这需要在前端构建配置里设对 base(Vite)或 publicPath(Webpack)。