【问题标题】:Can't go into object defined by rollup plugin-replace无法进入汇总插件替换定义的对象
【发布时间】:2022-01-07 08:08:57
【问题描述】:

在 Svelte 组件中,我试图访问我在汇总配置文件中设置的对象。 我的rollup.config.js 文件如下所示:

import replace from '@rollup/plugin-replace';

...
export default {
...
    replace({
        foo: JSON.stringify({ bar: 'Hello' }),
    }),

...

在我的 Svelte 组件中,一个简单的 console.log(foo) 可以工作:

但是当我尝试进入像 console.log(foo.bar) 这样的 foo 对象时,我得到 foo 未定义

【问题讨论】:

    标签: javascript svelte rollupjs svelte-3


    【解决方案1】:

    文档的这一部分解释了您的确切问题。
    https://github.com/rollup/plugins/tree/master/packages/replace#delimiters

    delimiters 选项控制字符串的匹配方式。默认delimiters['\b', '\b(?!\.)'],它只会替换foo,如果它遵循一个字边界并且后面是一个不是点的字边界。因此,对于您的rollup.config.js,行为将是

    console.log(foo)
    // becomes
    console.log({"bar":"Hello"})
    
    console.log(foo.bar)
    // is not replaced by the plugin as `foo` IS followed by a dot
    
    console.log(foo['bar'])
    console.log(foo .bar) // space after `foo`
    // both satisfy the delimiter check again and print: Hello
    // (horrible coding style in the latter but to illustrate how it works)
    
    const { bar } = foo
    // also satisfy the delimiter check hence
    console.log(bar) // prints: Hello
    

    如您所见,替换插件并没有真正解析您的代码,而只是执行简单的文本替换,与您的 IDE/编辑器的搜索和替换功能没有太大区别。高斯下面会说什么?

    console.log('foo')
    // Guess what?
    // ...
    // ...
    // printed: {"bar":"Hello"}
    // as if it were
    console.log('{"bar":"Hello"}')
    

    总之,您的解决方法可能是

    • foo['bar'],
    • const { bar } = foo,
    • 避免对象替换并使用诸如__FOO_BAR____FOO_BAZ__、...之类的键
    • 传递 delimiters: ['\\b', '\\b'] 以允许点跟随键。

    (但是在撰写本文时,由于等待合并的错误修复,最后一个似乎还没有工作)。
    https://github.com/rollup/plugins/pull/1088

    如果您使用delimiters: ['', ''],前面的警告需要更加谨慎。即使是字符串文字 'food' 或 HTML 模板标签 <footer> 也可能会更改为像 '{"bar":"Hello"}d'<{"bar":"Hello"}ter> 这样的乱码。因此,明智地命名您的密钥或根据您的使用情况使用一些不寻常的分隔符,例如旧版本的插件曾经演示过的内容:delimiters: ['<@', '@>']
    https://github.com/rollup/rollup-plugin-replace

    尽管如此,由于此类预处理非常初级,因此在添加替换键和使用它们时始终需要小心。

    【讨论】:

      【解决方案2】:

      好问题!对象 foo 仍未定义,因此它抛出了正确的错误,并且无法找到 foo 来替换您要替换的任何内容。

      解决方案是让替换插件完成它的工作。您可以在 js.svelte 文件中访问您的变量

      
      const { bar } = foo;
      
      console.log(bar);
      
      

      注意:对此插件进行了更改,请查看here 了解详细信息。如果您打算使用 dotenv 使用环境变量,请考虑

      import { config } from "dotenv";
      
      ...
      replace({
            values: {
              foo: JSON.stringify({ bar: "Hello", ...config().parsed }),
            },
          }),
      ...
      

      在你的苗条文件中

        const { bar, ...rest } = foo;
        console.log("bar=>", bar);
        console.log("env=>", rest);
      

      【讨论】:

      • 确实有效。有趣...虽然我不明白为什么破坏 foo 对象可以解决问题。
      • 替换插件正在寻找foo,如果是foo.bar,则无法这样做。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-09-09
      • 1970-01-01
      • 2018-05-13
      • 1970-01-01
      • 2021-10-05
      • 1970-01-01
      • 2016-01-28
      相关资源
      最近更新 更多