Next.js环境变量控制部署
Next.js 部署与 devops
前⾔
需要将 Next.js 部署到云平台上,同⼀份镜像,通过环境变量来控制项⽬的 api 链接,实现CI/CD 的流程。云平台框架使⽤的是 。Next.js 环境变量控制部署
⼀、安装cross-env
cross-env ⽤来设置环境变量,因为 win 和 linux 设置环境变量的⽅法不同,所以引⼊第三⽅库来⽅便设置
npm i --save cross-env
⼆、创建config⽬录
在根⽬录下创建 config ⽬录, 根据不同的 NODE_ENV 创建不同的⽂件夹, 底下新建不同的 dev ,test ⽂件。
dev ⽂件中,有 服务器地址等,ex : PORT=3000 …, test ⽂件也是
your-project
|- pages
|- public
+ |- config
+ |- development
+ |- dev
+ |- test
+ |- production
+ |- dev
+ |- test
dev 内容如下, ORIGIN ,NEXT_PUBLIC_ORIGIN 就是远程服务器的地址
HOST=xxxx
js获取json的key和valuePORT=8888
ORIGIN=xxxx:8888
NEXT_PUBLIC_ORIGIN=xxxx:8888
三、新建env.js⽂件
在根⽬录下新建 env.js ⽂件, .env.js 内容如下:
const fs =require('fs')
const path =require('path');
// 从环境变量中获取
const{NODE_ENV='production',RTE='test'}= v;
/
/封装 resolve
const resolve=(p)=> path.join(__dirname, p);
/**
* 读取⽂件
* ⽂件格式内容为
* TEST=ABC
* @param {路径} p 路径
* @return [[TEST:ABC]]
*/
const readEnv=(p)=>{
fs
.
readFileSync(resolve(p))
.toString()
.trim()
.split('\n')
.filter((l)=> l.indexOf('=')!==-1)
.map((v)=> v.split('='));
}
// 读取./config/development/{RTE}中的⽂件,
//
fs.writeFileSync(
resolve(`./.env.${NODE_ENV}.local`),
readEnv(`./config/${NODE_ENV}/${RTE}`)
.map(([key, value])=>`${key}=${value}`)
.join('\n'),
);
四、修改package.json⽂件
使⽤ cross-env 修改环境变量,然后 再运⾏ env.js ⽣成具体的配置⽂件,就会根据 /config/{NODE_ENV}/${RTE} ⽂件中的配置,设置环境变量
{
"scripts":{
"dev":"cross-env NODE_ENV='development' RTE='dev' ./env.js && next -p 3000",
"dev:test":"cross-env NODE_ENV='development' RTE='test' ./env.js && next -p 3000",
"debug":"cross-env NODE_OPTIONS='--inspect' next",
"lint":"eslint --ext .js,.jsx,.ts,.tsx ./",
"lint:fix":"yarn lint --fix",
"build":"next build --debug",
"start":"cross-env NODE_ENV='production' ./env.js && next start",
"pm2":"pm2 start ../../node_modules/next/dist/bin/next --name firmware-web -- start",
"stop":"pm2 stop firmware-web"
}
}
⾄此,就可以在本地,通过不同的环境变量,切换测试环境,开发环境,⽣成环境,下⼀步我们将部署到docker 容器中
部署到docker容器中
⼀、编写dockerfile⽂件
FROM node:lts
WORKDIR /app
COPY package.json ./
COPY yarn.lock ./
RUN yarn config set unsate-perm true
RUN yarn install --frozen-lockfile
COPY . .
ENV NODE_ENV=production
ENV RTE=dev
RUN chmod -R a+x ./env.js
RUN yarn build
EXPOSE 3000
CMD [ "yarn","start" ]
⼆、遇到的问题
前端 axios ⽆法获取到设置的环境变量,ORIGIN, NEXT_PUBLIC_ORIGIN 。
修改环境变量,⽆法正常的切换环境
三、如何解决
1. 前端 axios ⽆法获取到设置的环境变量,ORIGIN, NEXT_PUBLIC_ORIGIN 。因为 next.js 是服务端渲染框架,所以,会导致
.env.local 中的配置,前端可能⽆法及时的获取到,所以就要写⼀个动态 api ,
// /src/pages/api/envConfig.js
const envConfig =async(req, res)=>{
const{ORIGIN,NEXT_PUBLIC_ORIGIN}= v;
res.json({
ORIGIN,
NEXT_PUBLIC_ORIGIN,
});
};
export default envConfig;
在 axios 中,每次请求之前都去获取这个环境变量,可以考虑使⽤缓存把这两个变量保存下来,使⽤ sessionStorage 是为了避免另⼀个环境获取同样的配置。
quest.use(
async(config)=>{
// 判断 localStorage中是否有 _env, 如果有,就直接
// 获取,不在发送请求获取
let env;
Item('_env')){
env =JSON.Item('_env'));
}else{
env =('/api/envConfig');
sessionStorage.setItem(
'_env',
JSON.stringify({
ORIGIN: env.ORIGIN,
NEXT_PUBLIC_ORIGIN: env.NEXT_PUBLIC_ORIGIN,
}),
)
;
}
config.baseURL = env.ORIGIN|| env.NEXT_PUBLIC_ORIGIN;
const token = Item('_token')??'';
if(token){
config.headers.Authorization =`JWT ${token}`;
}
return config;
},
)
2. 修改环境变量,⽆法正常的切换环境。解决了第⼀个问题后,第⼆个问题就可以正常解决。
四、编译成docker镜像
使⽤ docker build 命令,将项⽬构建成镜像
docker build -t app:1.0.0 .
使⽤ docker run命令, 运⾏镜像成容器
docker run -d -p 3000:3000 -e RTE='dev'
通过 RTE 环境变量来控制容器的环境
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论