最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 前端如何获取到宿主机的环境变量?

    正文概述 掘金(Arow)   2020-12-05   491

    1. 前言

    2020.6.10 日我写了这样的一篇文章:

    Vue项目如何获取Docker的环境变量——最小完整实践

    里面简述了为什么要做这样一件事情,简单来说就是: 企业开发时多环境下需要前端页面通过获取宿主机的环境变量来动态的设置某个参数。

    在上面这篇博客中,我利用 docker 在构建镜像时获取系统环境变量来注入一个属性给 html 文件,然后获取这个对应的属性,挂载到 vue 或者全局即可。但是正如我在文末中写到,我并不是很喜欢这种方式,不优雅也不正式,同时文末我给提出了另一种解决之法。

    我思考和实践出了一种全新的方法,极度优雅和简单。

    2. 利用 docker 构建镜像时替换变量

    可能看标题,会觉得这跟第一种几乎相同,但是,这里的思想是不同的。 主要的区别在于一个是注入变量,一个是替换,一个是挂载变量然后获取,一个是直接获得,极度优雅。

    在此记录整个思考和实现的过程。

    2.1 思维转换

    最开始是怎么思考的呢?

    1. JS 能不能直接获取到环境变量,发现不行,因为 JS 是运行在解释器里面的。
    2. 能不能有一个桥梁,这个桥梁可以获取到环境变量,然后这个桥梁再把值传给JS (1) 首先,shell 可以直接获取到环境变量 (2) docker 在构建镜像时就可以运行 shell 脚本 (3) docker 可以做这样一个桥梁,获取到环境变量然后再把值注入到 html 文件中 这就是上面那篇文章实现的缘由。

    后来,渐渐的想到,既然docker构建镜像时可以运行shell,那为什么还要去注入变量,然后 JS 再获取变量呢?不可以直接进行文本替换吗?当我想到的时候,简直就是一句点醒梦中人。

    2.2 实现

    2.2.1 获取系统环境变量

    env 查看 然后 对应名字即可,比如对应名字即可,比如对应名字即可,比如PATH 下面是在 shell 脚本中获取环境变量

    #!/bin/bash
    path=$PATH
    
    2.2.2 sed 文本替换

    简单说明一下 sed 命令 全局替换

    sed 's/text/replace_text/g' file
    

    默认替换后,输出替换后的内容,如果需要直接替换源文件,使用 -i

    sed -i 's/text/replace_text/g' file
    

    (1) 首先,做一个简单的测试。

    前端如何获取到宿主机的环境变量?

    创建两个文件,a.txt 和 run.sh a.txt

    arrow is a frontend engineer.
    I am arrow
    

    run.sh

    #!/bin/bash
    sed -i 's/arrow/arrow_zb/g' ./a.txt
    

    运行 run.sh 文件

    sh run.sh
    

    运行 run.sh 后,a.txt 文件变为

    arrow_zb is a frontend engineer.
    I am arrow_zb	
    

    (2) 实际获取环境变量替换文件内容 通过以上测试,我想,你应该已经知道如何实现我们想要的功能了,不过我这里还是记录一下,因为这个过程中我还是遇到了一些问题,因为我使用的环境变量比较特殊,具体特殊之处往下一看便知。 假设我们想要获取系统变量 PATH, 将 a.txt 中的 arrow 替换成 $PATH。 根据上面的测试,我们可以写出如下脚本,run.sh 文件。

    sed -i '' "s/arrow/$PATH/g" ./a.txt
    

    此时运行 run.sh,理想状况下会直接将 a.txt 里面的 arrow 替换成 $PATH 的内容。 但是,运行就会报错

    sed: 1: "s/arrow//usr/local/bin: ...": bad flag in substitute command: 'u'
    

    原因很简单,你将 PATH 打印出来就知道了

    $ echo $PATH
    # /usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Library/Apple/usr/bin
    

    PATH 里面含有 / , 与此同时,我们的 sed -i '' "s/arrow/$PATH/g" ./a.txt 里的正则表达式定界符就是 / ,所以自然命令就混乱了,解决办法就是,将正则表达式定界符改成特别的即可,因为sed您可以使用任何定界符,例如改成如下:

    sed -i '' "s~arrow~$PATH~g" ./a.txt
    

    此时,运行即可生效,a.txt 的内容变成

    /usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Library/Apple/usr/bin is a frontend engineer.
    I am /usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Library/Apple/usr/bin
    

    即达到了我们想到的目的。 到此,实现了我们的功能,而且只用了一行代码,极度极度的优雅!

    2.3 实际应用

    在实际的应用中,我们一般是想通过获取系统的环境变量来实现动态的在某个文件中修改值或实现功能,在这里我就以获取系统的 ENV_SYSTEM (取值共 dev, text, beta, prod),来改变 api.js 文件中的 ENV_NOW.

    假设当前文件结构如下

    .
    ├── run.sh
    └── src
        └── api.js
    

    api.js 中内容如下:

    const origin = "www.ENV_NOW.arrow-zb.cn";
    
    export default {
      prefix: origin,
      get_user_list: {
        get: '/api/user/list'
      }
    }
    

    想要通过系统环境变量实现

    // dev
    "www.dev.arrow-zb.cn"
    // test
    "www.test.arrow-zb.cn"
    // beta
    "www.beta.arrow-zb.cn"
    // prod
    "www.arrow-zb.cn"
    

    那么在 run.sh 中首先应该获取系统变量,然后判断,然后替换即可。 以下就是简单的 shell 脚本了。

    #!/bin/bash
    ENV_NOW="."
    if [ $ENV_SYSTEM != '' ]
    then
      if [ $ENV_SYSTEM == 'prod' ]
      then
        ENV_NOW="."
      else
        ENV_NOW=".${ENV_SYSTEM}."
      fi
    fi
    
    sed -i '' "s/.ENV_NOW./$ENV_NOW/g" ./src/api.js
    

    测试:

    • 系统变量 ENV_SYSTEMdev

    运行 run.sh src/app.js 结果为

    const origin = "www.dev.arrow-zb.cn";
    
    export default {
      prefix: origin,
      get_user_list: {
        get: '/api/user/list'
      }
    }
    
    • 系统变量 ENV_SYSTEMprod

    运行 run.sh src/app.js 结果为

    const origin = "www.arrow-zb.cn";
    
    export default {
      prefix: origin,
      get_user_list: {
        get: '/api/user/list'
      }
    }
    

    完美的实现了预期的结果。 相信大部分同学看到这里已经知道如何在自己的项目中使用了,你就没必要看第三部分了。如果你还不知道,看第三部分,以真实的项目为例。

    3 真实项目 —— 以 vue 为例

    这里博主就不赘述简单的项目创建等,下面是使用 vue-cli 创建的简单示例。接下来一步一步的带领大家在真实项目中使用。

    前端如何获取到宿主机的环境变量?

    假设我在 src/api.js 中要 2.3 的需求。 同时我在 app.vue中将api打印出来做测试 前端如何获取到宿主机的环境变量?

    3.1 在根目录创建 run.sh 文件

    #!/bin/bash
    ENV_NOW="."
    if [ $ENV_SYSTEM != '' ]
    then
      if [ $ENV_SYSTEM == 'prod' ]
      then
        ENV_NOW="."
      else
        ENV_NOW=".${ENV_SYSTEM}."
      fi
    fi
    
    # mac 下
    # sed -i '' "s/.ENV_NOW./$ENV_NOW/g" ./src/api.js
    # 其他linux下
    sed -i "s/.ENV_NOW./$ENV_NOW/g" ./src/api.js
    
    npm i
    npm run build
    

    3.2 在根目录创建Dockerfile文件

    # 以nginx为基础镜像
    FROM nginx
    # 复制 ./dist/ 到 /usr/share/nginx/html/
    COPY ./dist/ /usr/share/nginx/html/
    # /usr/share/nginx/html/为 nginx 默认的启动文件夹
    

    3.3 在宿主机中运行

    将代码clone或移动到宿主机,运行 run.sh,其实一旦运行完成,就实现了获取宿主机的环境变量。

    bash run.sh
    

    3.4 docker构建并运行

    docker build -t programming-career .
    # 根据dockerfile来创建programming-career镜像
    docker run -p 6090:80 -d -t programming-career
    

    3.5 测试

    运行直接测试即可,博主将宿主机的ENV_SYSTEM设置为了beta, 最终博主的测试结果如下,完美的实现了

    前端如何获取到宿主机的环境变量?

    在这里贴出测试代码 点击查看

    4 总结

    从有这个想法到测试成功再到今天写博客,前后花了大量的时间,特别是写博客,更是花了不小于10个小时的时间,现在晚上快 9 点了,最终完成,虽然可能文本逻辑上还是不太好,但是尽量的做到了简单易懂,而且做了对应的测试,还适应了 mac 和 linux ,算是比较完整了。

    其实,只要理解了思路,你就会发现,其实很简单,而且很容易想到。


    起源地下载网 » 前端如何获取到宿主机的环境变量?

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元