NOTE
TIP对于拥有一定影响力的开源项目而言,可在 npm 官网查找它在某个大版本下的最新版本(带 lts/latest 标记)。
例如,查询 Node v16 和 Gatsby v3 下的最新版:
提升 Node 版本上限
:::danger 镜像 由于 CI 配置中调用了 rsync 包的相关命令,因此需要自行构建一个包含 rsync 模块的新镜像。 :::
- image: node:10.18.1-rsync
+ image: node:16.19.1-rsync
{
"name": "root",
"version": "0.1.0",
"engines": {
- "node": "10.18.1"
+ "node": ">= 16"
}
// ...
}
升级 Gatsby 及其相关插件
由于这些依赖为整个 monorepo 项目共用,因此安装时加上-W
参数将其提升至项目根部的 package.json 中。
yarn add -W \
gatsby@^3.15.0 \
gatsby-plugin-image@^1.15.0 \
gatsby-plugin-sharp@^3.15.0 \
gatsby-plugin-sitemap@^4.11.0 \
gatsby-plugin-react-helmet@^4.15.0 \
gatsby-plugin-styled-components@^4.15.0 \
gatsby-source-filesystem@^3.15.0 \
gatsby-source-contentful@^5.15.0 \
gatsby-transformer-sharp@^3.15.0
:::info 依赖安装策略 实际上在使用 npm/Yarn 等包管理器为 monorepo 项目安装依赖时,默认会将除可执行文件(.bin)之外的所有依赖包都安装到项目<根>目录下的 node_modules 中,此处仅提升公共依赖的「声明位置」以减少多个 package.json 文件维护同一份依赖版本数据的心智负担。 :::
问题处置
路由导航错误
import { navigate } from "gatsby";
navigate(path);
在旧版中,Gatsby 默认会对传给navigate
方法的path
参数中多余的/
进行去重处理:
//path//xxx -> /path/xxx
而在新版中,移除了这一默认行为,若path
存在多余的/
则会导致路由导航错误,因此需自行对path
做规范化处理:
import { navigate } from "gatsby";
/**
* @param {string} path navigate path
*/
function normalizePath(path) {
return path.replace(/\/+/g, `/`);
}
navigate(normalizePath(path));
依赖相关问题
❗️❗️❗️ 添补http-proxy-middleware
依赖与配置,解决本地代理错误问题:
yarn add -W -D http-proxy-middleware
+ const { createProxyMiddleware } = require('http-proxy-middleware')
+ const middleware = createProxyMiddleware({ secure: false, target: 'https://xxx.xxx.xxx' })
/** @type {import("gatsby").GatsbyConfig} */
module.exports = {
- proxy: [
- { url: 'https://xxx.xxx.xxx', prefix: '/api-xxx-1' },
- { url: 'https://xxx.xxx.xxx', prefix: '/api-xxx-2' },
- ],
+ developMiddleware: (app) => app.use('/api-xxx-1', middleware).use('/app-xxx-2', middleware),
}
❗️❗️❗️ 移除@hot-loader/react-dom
依赖与配置,目前已无用:
exports.onCreateWebpackConfig = ({ getConfig, stage }) => {
- const config = getConfig()
- if (stage.startsWith('develop') && config.resolve) {
- config.resolve.alias = {
- ...config.resolve.alias,
- 'react-dom': '@hot-loader/react-dom',
- }
- }
}
❗️❗️❗️ 添补gatsby-plugin-compile-es6-packages
依赖与配置,以解决在 Gatsby v3 版本下,插件gatsby-plugin-image
在 monorepo 项目里不能正常运作的问题:
yarn add -W gatsby-plugin-compile-es6-packages
module.exports = {
plugins: [
{
resolve: "gatsby-plugin-compile-es6-packages",
options: {
modules: ["gatsby-plugin-image"],
},
},
],
};
❗️❗️❗️ 由于 Webpack v5 版本不再提供自动引入 Node 模块对应的 polyfills 功能,因此需自行添加依赖与配置:
yarn add -W -D process path-browserify
/**
* @typedef {import("webpack").Configuration} WebpackConfiguration
*/
/** @type {(config: WebpackConfiguration) => WebpackConfiguration} */
const defineWebpackConfig = (config) => config;
/** @type {(args: import("gatsby").CreateWebpackConfigArgs) => void} */
exports.onCreateWebpackConfig = ({ stage, actions, plugins }) => {
const config = defineWebpackConfig({
plugins: [],
resolve: {
fallback: {
path: require.resolve("path-browserify"),
},
},
});
if (stage === "develop" || stage === "build-javascript") {
config.plugins?.push(plugins.provide({ process: "process/browser" }));
}
actions.setWebpackConfig(config);
};
迁移 gatsby-plugin-image
TIP官方迁移指南:https://www.gatsbyjs.com/docs/reference/release-notes/image-migration-guide/
官方插件文档:https://www.gatsbyjs.com/docs/reference/built-in-components/gatsby-plugin-image/
Step 1 - 配置添补
module.exports = {
plugins: [
// ...
"gatsby-plugin-image",
],
};
Step 2 - 导入变更
- import Img from 'gatsby-image'
+ import { GatsbyImage } from 'gatsby-plugin-image'
Step 3 - 查询变更
query {
banner: file(relativePath: { eq: "xxx/xxx.png" }) {
- childImageSharp {
- fluid(maxWidth: 1920, quality: 100) {
- ...GatsbyImageSharpFluid
- }
+ gatsbyImageData(quality: 100)
}
}
}
Step 4 - 使用变更
+ import { getImageData } from 'gatsby-plugin-image'
function Comp() {
return (
<Fragment>
- <GatsbyImage fluid={banner.childImageSharp.fluid} />
{/* 需要必传 alt 属性 */}
+ <GatsbyImage alt="xxx-xxx" image={getImageData(banner)} />
{/* or */}
+ <GatsbyImage alt="xxx-xxx" image={banner.childImageSharp.gatsbyImageData} />
</Fragment>
)
}
- <GatsbyImage
- fluid={[
- data.bannerMb.childImageSharp.fluid,
- {
- ...data.banner.childImageSharp.fluid,
- media: `(min-width: 813px)`,
- },
- ]}
- />
+ <GatsbyImage
+ alt='xxx-banner'
+ image={isSmall ? getImageData(data.bannerMb) : getImageData(data.banner)}
+ />
迁移 gatsby-plugin-sitemap
Step 1 - 配置变更
module.exports = {
plugins: [
{
resolve: 'gatsby-plugin-sitemap',
options: {
- exclude: ['*/404/', '*/404.html'],
+ excludes: ['*/404/', '*/404.html'],
},
},
],
}
Step 2 - 规则变更
:::danger 站点地图抓取规则
插件gatsby-plugin-sitemap
在新版本中遵循了索引文件的定义规范,改变了创建 sitemap.xml 的规则:
旧规则:直接创建一个 xxx-sitemap.xml 文件。
新规则:先对 URL 条目进行拆分,每 45000 条拆分为一个 xxx-sitemap-0.xml 文件,以此类推 1-2-3-…,最后再创建一个 sitemap-index.xml 索引文件,重定向到拆分后的 xml 文件。 :::
由于百度不支持 sitemap-index.xml 这类索引文件的重定向(据说是为了打击非法产业与泛目录类网站),并且gatsby-plugin-sitemap
也无选项可配置回退旧规则,因此需与营销同事协调改动。
Step 2.1 - 配置变更
由于规则从直接创建文件调整为了文件拆分,因此输出的是一个目录,对输出地址做语义化处理:
module.exports = {
plugins: [
{
resolve: 'gatsby-plugin-sitemap',
options: {
- output: `/xxx-sitemap.xml`,
+ output: `/xxx-sitemap`,
},
},
],
}
Step 2.2 - 上传地址
打包后输出的目录结构如下所示:
public
└─ xxx-sitemap
├─ sitemap-0.xml
└─ sitemap-index.xml
需要营销同事重新上传此地址,例如:https://domain/package-name/xxx-sitemap/sitemap-0.xml
。