创建时间:2023-09-05
更新时间:1 分钟前
小明搞到一台服务器,用 Nextjs 搭建了一个简单的网页应用,部署到了服务器上。由于服务器带宽低,访问网页发现脚本加载很慢,于是小明考虑将静态资源上传到 CDN,减轻服务器压力,还能享受 CDN 带来的其他好处。
以 Nextjs13 版本为例,在部署项目之前,我们都会执行一次 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
字段:
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/
开头。
这里的域名 https://cdn.mydomain.com
,只是个示例,要换成 CDN 厂商实际给的真实域名。
现在我们已经修改好路径了, /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
访问到脚本。
很多云服务商提供对象存储服务,可能需要额外花钱,但如果网站访问量小,一个月才花几毛钱到几块钱。这里以阿里云 OSS 为例,阿里云 OSS 是什么?怎么搞?这里就不多讲了,搞好之后你应该会拿到 accessKeyId,accessKeySecret,region,bucket 这四样东西。
如果你的阿里云 OSS 的加速域名为 your-cdn.oss-accelerate.aliyuncs.com
,将 assetPrefix
设置为 https://your-cdn.oss-accelerate.aliyuncs.com
。
Nextjs 用的是 webpack 构建脚本的,所以我们需要写一个,或者找一个 webpack 插件,用来将构建好的脚本上传到阿里云 OSS,就用 next-oss-webpack-plugin
插件吧,先安装一下 npm i next-oss-webpack-plugin --save-dev
。
打开 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/
,比如上面的 https://your-cdn.oss-accelerate.aliyuncs.com/_next/static/chunks/10361123-9db6883597b575ca.js
。
不能上传为 https://your-cdn.oss-accelerate.aliyuncs.com/chunks/10361123-9db6883597b575ca.js
或者 https://your-cdn.oss-accelerate.aliyuncs.com/10361123-9db6883597b575ca.js
,错误的上传路径会导致 404 not found。