小项目用根目录+css/js/images/pages四文件夹,够用零配置;中大型项目必须分src/dist,否则路径混乱、协作困难。小项目指单人维护、页面≤5个、无构建需求的静态站,核心是路径稳定、一眼可定位:index.html放根目录,css/只放main.css和reset.css,js/仅存main.js和utils.js,images/按icons/banner分但不超过两层,多页面统一放pages/about.html等。

小项目直接用根目录 + css/、js/、images/、pages/ 四个文件夹,够用且零配置;中大型项目必须上 src/ 和 dist/,否则改两行代码就要全局修路径。
小项目怎么放文件才不翻车
所谓“小项目”,指单人维护、页面 ≤ 5 个、不用 Sass/ES6/模板语法的纯静态站。这类项目最怕路径写错导致本地双击打开白屏、上线后图片全挂、导航加载失败。
-
index.html必须放在根目录,这是所有服务器默认找的首页,别挪到pages/里再配重定向 -
css/下只放main.css和reset.css,别建css/base/或css/v2/—— 没构建工具时,多一层就多一个相对路径计算错误点 -
js/里只放main.js和utils.js,避免js/lib/dom.js这种嵌套,否则pages/about.html里写<script src="js/main.js"></script>会去查pages/js/main.js,而不是你预期的根目录下那个 -
images/可分icons/、banner/,但别超过两层,比如images/icons/social/twitter.svg已经难定位、难迁移 - 所有内部链接用相对路径:
pages/contact.html,不是/pages/contact.html—— 后者在本地双击打开时会触发浏览器安全策略,直接 404
中大型项目为什么必须分 src 和 dist
一旦开始用 Sass、ES6 模块、Nunjucks 模板或 Vite 构建,源码和上线文件混在一起就是定时炸弹:本地跑得通,构建后 CSS 路径全错;改一个颜色变量,要手动同步三处;别人接手第一件事是删掉整个目录重来。
-
src/存所有可编辑源码:src/html/(含index.njk)、src/css/scss/(main.scss)、src/js/modules/(nav.js) -
dist/是构建产物,只含最终能上线的文件:index.html、css/main.css、js/main.js,禁止手动修改 -
public/存不参与构建的静态资源:public/favicon.ico、public/robots.txt,构建时原样复制进dist/,别丢进src/里——Webpack/Vite 默认不处理src/下的非源码文件 - HTML 中所有资源引用必须用根相对路径:
<link rel="stylesheet" href="/css/main.css">,不是../css/main.css—— 前者以域名根为基准,后者依赖当前 HTML 文件位置,pages/about.html和blog/post.html的..层数不同,极易断裂
components/ 目录能不能直接浏览器里用
不能。把 components/header.html 放进项目、再用 fetch() 加载它,在本地双击打开或某些开发服务器下会直接触发 CORS 或跨域读取失败,这不是结构问题,是浏览器安全机制。
立即学习“前端免费学习笔记(深入)”;
- 真要组件化,只有两种落地方式:构建时合并(如
gulp-file-include),或服务端启用 SSI(<!--#include file="header.html" -->) -
components/header/下必须严格有header.html、header.css、header.js三件套,命名不一致会导致脚本找不到对应样式 - 组件内禁止用
../../css/base.css这类向上跳转的相对路径 —— 移动组件目录时所有引用全崩,应统一用根路径/css/base.css -
pages/about.html引用组件时,路径计算基准是pages/目录,不是项目根,所以<script src="../components/header/header.js"></script>才对,不是./components/...
多页面共用 JS 怎么避免重复执行
硬写 <script src="js/app.js"></script> 到每个 pages/*.html 里,会导致所有页面都执行全部逻辑:contact.html 初始化了代码高亮,blog.html 却绑了表单验证事件,结果点提交按钮没反应,控制台还报 Cannot read property 'addEventListener' of null。
- JS 入口保持单一,但按页面条件初始化模块:
if (document.body.classList.contains('page-contact')) { initFormValidation(); } - 用
data-page属性替代 class 判断更稳妥:<body data-page="contact">→if (document.body.dataset.page === 'contact') { ... } - 避免在 JS 里硬编码 DOM 选择器,比如
document.querySelector('#contact-form'),应先检查元素是否存在,再操作,否则其他页面因缺失该节点而报错中断 - 如果用了构建工具,可通过环境变量注入页面标识,比如 Vite 中在
index.html写<script>window.PAGE = ''</script>,再在main.js里分支加载
最常被忽略的一点:路径是否稳定,不取决于你画了多少层级图,而取决于浏览器解析时的当前 HTML 文件位置。哪怕结构再“规范”,只要一个 <img src="logo.png"> 没写对上下文,整页资源就断链。动手前先想清楚这个 HTML 文件在哪、它要加载的文件实际在哪、浏览器会怎么拼路径。



















