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对象的内容和实际的内容是有出入的。

  • 相关阅读:
    1060. Are They Equal (25)
    1063. Set Similarity (25)
    Java基础学习总结(20)——基础语法
    Java基础学习总结(19)——Java环境变量配置
    Java基础学习总结(19)——Java环境变量配置
    Java基础学习总结(18)——网络编程
    Java基础学习总结(18)——网络编程
    Java基础学习总结(17)——线程
    Java基础学习总结(17)——线程
    Java基础学习总结(16)——Java制作证书的工具keytool用法总结
  • 原文地址:https://www.cnblogs.com/liulun/p/14106682.html
Copyright © 2011-2022 走看看