将 Nextjs 中的脚本上传到 CDN,可以减轻服务器压力并享受 CDN 带来的其他好处。
以 Next.js 13 为例,部署项目前我们会执行一次 next build
命令,该命令会生成一个 .next
目录,里面存放了很多脚本。
部署后访问页面时,可以发现 script
标签的 src
属性都以 /_next/static/
开头。
这个路径实际上对应 .next/static/
目录。比如 /_next/static/chunks/10361123-9db6883597b575ca.js
对应 .next/static/chunks/10361123-9db6883597b575ca.js
文件。
现在,我们需要把 .next/static/
目录下的文件上传到 CDN,并修改 src
为对应的 CDN 地址。
修改配置文件
打开 next.config.js
文件,新加一个 assetPrefix
字段,assetPrefix 官方文档
const isProd = process.env.NODE_ENV === "production";
module.exports = {
assetPrefix: isProd ? "https://cdn.mydomain.com" : undefined,
};
重新构建和部署后,访问页面时脚本地址会变成:
即在 /_next/static/
路径前加上了 assetPrefix
。
assetPrefix
不仅可以是域名,还可以在域名后加其他路径。
比如 https://cdn.mydomain.com/tag_1.0
,这样生成的脚本地址会以 https://cdn.mydomain.com/tag_1.0/_next/static/
开头。
现在路径已经修改好了,/static/chunks/10361123-9db6883597b575ca.js
变成了 https://cdn.mydomain.com/_next/static/chunks/10361123-9db6883597b575ca.js
。
接下来要上传脚本到 CDN,使其可以通过 https://cdn.mydomain.com/_next/static/chunks/10361123-9db6883597b575ca.js
访问。
上传资源到 CDN
很多云服务商提供对象存储服务,可能需要花钱,但如果网站访问量小,费用很低。
这里以阿里云 OSS 为例,阿里云 OSS 是什么及其使用方法这里不多讲,使用后你会拿到 accessKeyId
、accessKeySecret
、region
、bucket
这四样信息。
如果阿里云 OSS 的加速域名为 your-cdn.oss-accelerate.aliyuncs.com
,则将 assetPrefix
设置为 https://your-cdn.oss-accelerate.aliyuncs.com
。
Next.js 用 webpack 构建脚本,我们需要编写或者找一个第三方的 webpack 插件,将构建好的脚本上传到阿里云 OSS。
以 next-oss-webpack-plugin
插件为例,打开 next.config.js
文件,加入如下代码
const NextOSSPlugin = require("next-oss-webpack-plugin");
const isProd = process.env.NODE_ENV === "production";
const assetPrefix = isProd
? "https://your-cdn.oss-accelerate.aliyuncs.com"
: undefined;
module.exports = {
//...
assetPrefix,
webpack(config, { buildId }) {
if (isProd && buildId) {
config.plugins.push(
new NextOSSPlugin({
region: "", // bucket 所在区域,比如 oss-cn-hangzhou
accessKeyId: "",
accessKeySecret: "",
bucket: "", // bucket 的名称,比如 my-cdn
filter: (assert) => /^static\/.*/.test(assert),
assetPrefix: `${assetPrefix}/_next/`, // 上传资源前缀
})
);
}
return config;
},
//...
};
提示
记得先安装插件
上述 accessKeyId
、accessKeySecret
、region
、bucket
都可以在阿里云中获取。
执行 next build
时,这个插件会将 .next/static/
目录下的资源(包括脚本和 JSON 文件)上传到阿里云 OSS,这样就可以通过加速域名或 CDN 域名访问到这些资源。
其他云服务商的实现方式类似,特别需要注意的是,上传到云端的路径要包含 /_next/static/
,错误的上传路径会导致 404 not found。