自动化与脚本
用 netlify.toml、_redirects…
在 Netlify 上配置构建命令、发布目录、重定向/重写/代理、自定义响应头、环境变量与密钥、函数打包、忽略构建及 monorepo/SPA 时使用。
🧪 尚未被验证(还没有小呱复用过的记录,不代表不好)
GDI C 38/100
进化评分(GDI)
综合排序依据 —— 四个维度的加权结果,让你看出「为什么这条排在前面」
内在质量 55/100 ×0.35
使用度 0/100 ×0.30
口碑 50/100 ×0.20
新鲜度 59/100 ×0.15
适用场景
用 netlify.toml、_redi特定
解决思路
- 把配置放在仓库根目录(monorepo 则放在 base/package 目录)的三个文件中:`netlify.toml`(构建、contexts、插件、函数、重定向、headers、dev)、`_redirects`(纯文本重定向/重写规则,保存到 publish 目录,无扩展名)、`_headers`(纯文本响应头,保存到 publish 目录)。
- 记住 `netlify.toml` 的值与 Netlify UI 冲突时以 toml 为准;toml 中的路径是相对于 base 目录(默认根 `/`)的绝对路径。
- 优先使用现代语法:函数打包用 `node_bundler = "esbuild"`(`zisi` 是旧版 JS 默认,TypeScript 始终用 esbuild);临时重定向用 `status = 302`(不支持 307);Gatsby Image CDN 用 `NETLIFY_IMAGE_CDN` 而非废弃的 `GATSBY_CLOUD_IMAGE_CDN`。
- 不要在 TOML 中用 `key = "$VAR"` 注入环境变量值(代理重定向的 `signed` 除外);改用构建命令中的 `sed` 替换或构建插件。
- 在 `[build]` 中设置 `base`、`publish`、`command`、`environment`;用 `[context.production]`、`[context.deploy-preview]`、`[context."feat/branch"]`(含特殊字符的名称要加引号)做按上下文覆盖。
- 注意 `[build]` 在 Bash 中运行;context 感知的键只有 `[build]` 和 `[[plugins]]`,`[[redirects]]` 与 `[[headers]]` 始终是全局的;优先级从低到高:UI < toml < 任意 context 属性 < `[context.<name>]` < `[context.branchname]`。
- 重定向规则先处理 `_redirects` 再处理 `netlify.toml`,各自内部自上而下第一条匹配生效,所以具体规则要放在通用规则之前;Edge Functions 在重定向之前运行。
- 为 SPA 的 history-pushState 添加回退:`_redirects` 中写 `/* /index.html 200`,或 TOML 中写 `[[redirects]] from = "/*" to = "/index.html" status = 200`。
- 按 `from to [status] [conditions]` 语法编写 `_redirects`:支持 `#` 注释、路径大小写敏感、特殊字符需 URL 编码;示例包括 301/302/404、重写 200、强制/遮蔽 `200!`、splat `/news/* /blog/:splat`、占位符 `/news/:month/:date/:year/:slug`、查询参数 `/store id=:id /blog/:id 301`、条件 `Country=au,nz`、`Language=he`、`Cookie=is_legacy,my_other_cookie`(值列表内不能有空格)。
- 在 `[[redirects]]` 中使用关键字 `from`、`to`、`status`(默认 301)、`force`(默认 false,`!`/shadow)、`query`(如 `query = {path = ":path"}`)、`conditions`(`{Language, Country, Role, Cookie}`)、`headers`(代理请求头)、`signed`(签名代理的环境变量名)。
- 避免重定向陷阱:不能用重定向增删尾部斜杠(CDN 先规范化 URL,`/x/ → /x 301!` 会无限循环),依赖默认开启的 Pretty URLs;splat 星号只能在段末尾(`/jobs/*` 合法,`/jobs/*.html` 非法);占位符 `:x` 只能在段开头,同一段不能混用通配符和占位符;无法从 splat 中排除路径,需把更具体的规则放前面;`Country` 用 ISO 3166-1 alpha-2,语言重定向只匹配 `Accept-Language` 的第一项;外部认证提供商的基于角色的重定向仅限 Enterprise;超过 10,000 条重定向时改用通配符/占位符或 Edge Functions,否则序列化输出过大会导致部署失败。
- 配置代理:`/api/* https://api.example.com/:splat 200`,或指向其他 Netlify 站点时用 `.netlify.app` 域名而非自定义域名;TOML 中可加 `force = true` 和 `headers = {X-From = "Netlify"}`;签名代理用 `signed = "API_SIGNATURE_TOKEN_PLACEHOLDER"`(该环境变量作用域须含 Runtime,必须写在 `netlify.toml`,JWS 仅限外部,不适用于 Netlify→Netlify)。
- 代理陷阱:不允许跨团队重写;同密码站点可重写但不能跨不同受保护站点;代理超时 26 秒;默认只有一跳;相对路径资源会失效(用绝对路径或 `<base>`);循环会被静默忽略。
- 在 `_headers` 或 `[[headers]]` 中设置自定义响应头,多值可重复键或用 TOML 多行字符串;注意 headers 是全局的,不按分支/context 作用域。
- 若需按 context 设置 headers,先移除全局 headers,把 header 文件放在自定义目录,并在按 context 的构建命令中 `cp` 到 publish 目录,例如 `[context.staging] command = "npm run build && cp ./custom-headers/_stagingHeaders ./dist/_headers"`。
- 注意 headers 只作用于 Netlify 存储的文件,不作用于代理内容或函数/edge(SSR)响应,后者须自行设置;`Content-Length`、`Content-Encoding`、`Location`(用重定向)、`Set-Cookie`、`Server` 等名称会被忽略(由服务器设置);Basic auth headers 仅 Pro/Enterprise;跨子域 cookie 需要自定义域名(`netlify.app` 在 Public Suffix List 上)。
- 配置函数:`[functions]` 中设 `directory`(默认 `<base>/netlify/functions`)、`node_bundler = "esbuild"`、`external_node_modules`(仅 esbuild,用于原生插件等)、`included_files`(`!` 前缀表示排除);用 `[functions."api_*"]` 等 glob/命名块与顶层配置拼接。
- 选择环境变量存储方式:UI/CLI/API 存在 Netlify 上(不在仓库),支持站点+共享变量、按 context 的值、作用域,可到达构建、函数/edge/ODB、snippet 注入、表单、签名代理,敏感内容推荐用这种方式;`netlify.toml` 存在仓库中,仅站点变量、按 context 的值、无作用域选择(全部获得 Builds + Post processing),只能到达构建和 snippet 注入。
- 注意 `netlify.toml` 中的环境变量会覆盖同名的 UI/CLI/API 变量;在 TOML 中按 context 设置值,如 `[context.production] environment = { NODE_VERSION = "14.15.3" }`、`[context.deploy-preview.environment]`、`[context.branch-deploy.environment]`。
- 用 CLI 管理环境变量:`netlify env:set KEY value`(`--secret` 标记为密钥)、`netlify env:import .env`(`--replace-existing` 先清空其他)、`netlify env:unset KEY`、`netlify env:list --plain --context production > .env`、`netlify build`(用 Netlify 的环境变量本地构建);API 用 `createEnvVars` / `updateEnvVar`(`is_secret: true`)/ `setEnvVarValue` / `deleteEnvVar` / `deleteEnvVarValue`。
- 访问语法:`build.command`/`ignore.command` 中用 Bash `$VAR`;Node 脚本和插件中用 `process.env.VAR`。
- 了解作用域(Pro/Enterprise,默认全部):Builds(站点构建)、Functions(Functions/Edge/ODB)、Runtime(表单、签名代理)、Post processing(snippet 注入);共享变量为 Pro/Enterprise 且仅 Team Owner 可读/编辑;站点+共享键冲突时按作用域分别解析,站点变量只在其实际携带的作用域内胜出。
- 遵守命名/限制:键只能字母数字加下划线且必须以字母开头(`1KEY`、`_KEY1` 非法);键 ≤255 字符,值 ≤5,000 字符;只读变量名保留;更改后需重新构建并部署。
- 用保留配置变量设置构建语言:`NODE_VERSION`、`NPM_FLAGS`、`YARN_VERSION`、`BUN_VERSION`、`RUBY_VERSION`、`PHP_VERSION`、`PYTHON_VERSION`、`GO_VERSION`、`HUGO_VERSION`、`PNPM_FLAGS`、`NPM_TOKEN`(Yarn 用 `YARN_NPM_AUTH_TOKEN`)等。
- 必须在 UI/CLI/API 而非 `netlify.toml` 中设置的变量(在仓库克隆后或仅运行时读取):`AWS_LAMBDA_JS_RUNTIME`、`GIT_LFS_ENABLED`、`GIT_LFS_FETCH_INCLUDE`、`NETLIFY_BUILD_DEBUG`。
- 处理 `CI` 陷阱:`CI` 默认为 `true`,若破坏构建则在构建命令前加 `CI='' `。
- 向 headers/redirects 注入环境变量值:`key = "$VAR"` 不支持,只能用路径(作用域须含 Builds),例如 `[build] command = "sed -i \"s|HEADER_PLACEHOLDER|${PROD_API_LOCATION}|g\" netlify.toml && yarn build"`;`sed` 替换仅对 `[[headers]]`/`[[redirects]]` 有效(构建后读取),且对构建插件不可见(插件在构建命令前运行);要让插件可见,用本地构建插件修改 `netlifyConfig`。
- 利用只读构建变量:`CONTEXT`(`production`/`deploy-preview`/`branch-deploy`/`dev`)、`BRANCH`、`COMMIT_REF`、`CACHED_COMMIT_REF`、`PULL_REQUEST`、`REVIEW_ID`、`URL`、`DEPLOY_URL`、`DEPLOY_PRIME_URL`、`SITE_ID`、`SITE_NAME`。
- 标记密钥变量:UI 中勾选 `Contains secret values`,CLI 用 `--secret`,API 用 `is_secret: true`;强制策略:密钥值只写不可读(设置后无版本可读,不能移除标记来查看);密钥需要显式 contexts + scopes,不能带 `post processing` 作用域;只有 Netlify 上的代码(edge/serverless/build)能读未掩码值,Netlify 之外看到掩码;`dev` context 的值例外(从 UI/CLI/API 未掩码),`netlify build` 从不输出原始值。
- 配置密钥扫描:一旦有密钥变量即自动运行(也通过智能检测);检测到会失败构建并记录位置;通过按 context 设置的环境变量配置:`SECRETS_SCAN_ENABLED=false` 禁用全部扫描(失去所有密钥保护)、`SECRETS_SCAN_SMART_DETECTION_ENABLED=false` 仅禁用智能检测、`SECRETS_SCAN_OMIT_KEYS`、`SECRETS_SCAN_OMIT_PATHS`(逗号列表,路径从仓库根算,支持 glob)、`SECRETS_SCAN_SMART_DETECTION_OMIT_VALUES` 白名单误报(优先用它而非禁用;智能检测为 Personal/Pro/Enterprise)。
- 了解扫描范围:覆盖所有构建文件,值 >4 字符且非布尔,搜索明文 + base64 + URI 编码的排列。
- 对公开仓库配置敏感变量策略(Project configuration > Environment variables > Site policies),决定不可信部署(未识别作者)是否获得敏感变量;站点成员的 Git 部署始终可信,即使来自 fork;选项:`Require approval`(默认,不可信部署等待成员批准)、`Deploy without sensitive variables`(构建运行但扣留敏感变量)、`Deploy without restrictions`(所有变量可用);GitHub Enterprise Server / GitLab 自托管仓库不可用(视为私有)。
- 用 `[build]` 下的 `ignore` 决定是否重建:从 base 目录在 Bash(或 Node.js 18,固定;站点 `package.json` 依赖不可用)中运行;退出 `1` = 有变化 → 继续构建,退出 `0` = 无变化 → 停止构建;构建钩子始终构建,忽略退出码;示例 `ignore = "git diff --quiet $CACHED_COMMIT_REF $COMMIT_REF packages/blog-1 packages/common"`、`ignore = "node ignore_build.js"`(独立文件路径须以 `./` 开头)、`process.exitCode = process.env.BRANCH.includes("debug") ? 0 : 1`。
- 配置 monorepo:把站点子目录设为 package directory(其 `netlify.toml` 放在那里),base 保持根 `/`,在子目录级别声明依赖;package directory 只能在 UI 设置(Project configuration > Developer settings > Continuous deployment > Build settings),不能在 `netlify.toml` 中设置;配置文件发现顺序:package dir → base dir → root;toml 中路径仍相对于 base 目录;用 `netlify <cmd> --filter <site>` 选择站点。
- 配置 JavaScript SPA:构建命令 `npm run <script>` / `yarn <script>`,publish 目录常为 `dist`(取决于框架);为 pushState 路由添加 `/* /index.html 200` 回退;代码分割 + 哈希文件名配合原子部署可能因陈旧引用抛出 `Uncaught SyntaxError: Unexpected token`,可禁用哈希文件名、使用永久链接或 service worker。
- 配置 Netlify Dev `[dev]`:不在 Bash 中运行(`command` 中不能用 Bash 语法);没有 `environment` 键,本地环境变量设在 `[context.dev.environment]`;可设 `command`、`targetPort`(若同时设 command + targetPort,framework 必须为 `"#custom"`)、`port`、`framework`、`[dev.https]` 的 `certFile`/`keyFile`。
- 配置插件与扩展:`[[plugins]]` 中设 `package` 和 `[plugins.inputs]`;`[[integrations]]` 为构建时扩展,需先在团队安装,设 `name` 和 `[integrations.config]`。
- 遵守组织约定:`netlify.toml` 中设置的环境变量在函数或 edge functions 运行时不可用(读取返回 `undefined`),运行时变量要用 UI 或 `netlify env:set` 设置。
- 绝不把密钥放在客户端前缀的环境变量中(`VITE_`、`NEXT_PUBLIC_`、`PUBLIC_` 等),它们会被内联进客户端 bundle,`--secret` 也无法保护。
- 本地快照环境变量(`netlify env:list --plain > .env`)时保持 `.env` 在 gitignore 中,绝不提交。
- 明确说明环境变量作用域交互:作用域为 Builds 的站点变量不会在其他作用域遮蔽共享变量——优先级按作用域独立解析(站点仅在其实际携带的作用域内胜过共享)。
适用边界 · 注意事项
- 不使用 Netlify 平台(其他托管/静态站点服务)时。
- 没有 Netlify 账号或未使用 Netlify 的构建、重定向、函数、环境变量功能时。
- 需要的能力属于 Netlify 付费计划限制(如 Basic auth headers 需 Pro/Enterprise、共享变量需 Pro/Enterprise、外部认证提供商的角色重定向需 Enterprise)且当前计划不支持时。