zoukankan      html  css  js  c++  java
  • 谈Vite在Electron环境下吃花卷拉馒头的现象

    缘起

    在Electron的渲染进程中(也就是页面代码中),

    我们常常使用process.env来携带一些环境变量,

    比如HTTP服务地址的基质,本地静态资源的路径等

    这样做主要有两个目的

    一个是方便开发者写多个配置环境变量的文件,区分生产环境、测试环境和开发环境

    另一个是主进程和渲染进程共享一套环境变量,全局任何一个地方都随取随用,非常方便

    正因为如此,一般的编译工具都不会动用户的process对象

    但Vite不一样,Vite的作者认为Vite只是给Web(运行在浏览器中的)产品提供服务的,

    所以编译时把用户的process对象吃掉没关系,甚至可以拉一个完全不一样的东西给开发者都没影响

    因为Web前端开发者用不到这个对象

    哎,尤雨溪完全忽略了Electron开发者的感受

    现象

     用Vite创建一个Vue3项目,在入口文件中输出这两个对象

    console.log(process)
    console.log(process.env)

    然后用Vite编译,Electron打包编译的文件,安装并启动Electron,打开调试器,

    process对象的输出如下(注意process下env属性是正常的):

    process.env对象的输出如下:

    为什么会出现这种现象呢?我们打开Vite编译后的文件,找到目标位置,发现代码被转化成了这个样子:

      console.log(process);
      console.log({NODE_ENV: "production"});

    process还是老样子,但process.env被直接转成了一个对象字面量  

    原理

    想来Vite这么做可能的原因是:

    在process.env下加属性是Node.js开发者最常用的区分生产环境和开发环境的方案了

    但浏览器环境下根本就没有process对象,那怎么办呢?

    就直接粗暴的改写了开发者的代码吧

    把process.env转码成了{NODE_ENV: "production"}

    于是,就是现在我们看到的结果

     翻翻Vite的代码,确实找到了如下逻辑(这是最新的代码,以前我看到的跟这还不一样):

          createReplacePlugin(
            (id) =>
              !/?vue&type=template/.test(id) &&
              // also exclude css and static assets for performance
              !isCSSRequest(id) &&
              !resolver.isAssetRequest(id),
            {
              ...defaultDefines,
              ...userDefineReplacements,
              ...userEnvReplacements,
              ...builtInEnvReplacements,
              'import.meta.env.': `({}).`,
              'import.meta.env': JSON.stringify({
                ...userClientEnv,
                ...builtInClientEnv
              }),
              'process.env.NODE_ENV': JSON.stringify(resolvedMode),
              'process.env.': `({}).`,
              'process.env': JSON.stringify({ NODE_ENV: resolvedMode }),
              'import.meta.hot': `false`
            },
            !!sourcemap
          ),

    就是这段代码转写了我们业务代码中的process.env

    元凶找到,就有相应的解决方案了

    方案

    最老的版本的Vite,只能这样做才可以

    eval(['process',"env"].join('.'))

    当前版本的Vite,这样写也可以的:

    process["env"]

    官方推荐使用的方式

    import.meta.env

    但我不推荐这样用,这种写法拿到的env对象的内容和实际的内容是有出入的。

  • 相关阅读:
    ubuntu远程windows桌面
    spring boot 给返回值加状态 BaseData
    spring boot 拦截异常 统一处理
    IntelliJ IDEA spring boot 远程Ddbug调试
    IntelliJ IDEA 常用插件
    spring boot 请求地址带有.json 兼容处理
    spring boot 接口返回值去掉为null的字段
    spring boot 集成disconf
    Spring boot 自定义拦截器
    Linux下安装MySQL
  • 原文地址:https://www.cnblogs.com/liulun/p/14106682.html
Copyright © 2011-2022 走看看