In a Svelte component, I'm trying to access an object I set up in my rollup config file.
My rollup.config.js file looks like this:
import replace from '@rollup/plugin-replace';
...
export default {
...
replace({
foo: JSON.stringify({ bar: 'Hello' }),
}),
...
In my Svelte component, a simple console.log(foo) works:
But when I try to go into that foo object like console.log(foo.bar), I get foo is not defined:
Good question! The object foo remains undefined so it is throwing the right error, and is unable to find foo to replace with whatever you are going to replace it with.
The solution is having the replace plugin do its job. You may access your variable like this in your js or your .svelte files
const { bar } = foo;
console.log(bar);
Note: there was a change made to this plugin check here for details. if you are planning to use environment variables using dotenv consider
import { config } from "dotenv";
...
replace({
values: {
foo: JSON.stringify({ bar: "Hello", ...config().parsed }),
},
}),
...
and in your svelte file
const { bar, ...rest } = foo;
console.log("bar=>", bar);
console.log("env=>", rest);
This section of the document explains your exact problem.
https://github.com/rollup/plugins/tree/master/packages/replace#delimiters
The delimiters option controls how the strings will be matched. With the default delimiters being ['\b', '\b(?!\.)'], it would only replace foo if it follows a word boundary and is followed by a word boundary that is not a dot. Hence with your rollup.config.js the behaviour would be
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
As you see, the replace plugin doesn't really parse your code but instead only preforms simple text replacement not too different from the search-and-replace feature of your IDE/editor. Gauss what would it say below?
console.log('foo')
// Guess what?
// ...
// ...
// printed: {"bar":"Hello"}
// as if it were
console.log('{"bar":"Hello"}')
To conclude, your workaround might be
foo['bar'],const { bar } = foo,__FOO_BAR__, __FOO_BAZ__, ...delimiters: ['\\b', '\\b'] to allow dots following the key.(However at the moment of writing, the last one doesn't seem to work yet due to a bugfix waiting to be merged).
https://github.com/rollup/plugins/pull/1088
If you use delimiters: ['', ''] the earlier caveat requires much higher level of caution. Even a string literal 'food' or a HTML template tag <footer> might be changed to gibberish like '{"bar":"Hello"}d' or <{"bar":"Hello"}ter>. So name your keys wisely or use some unusual delimiters depending on your usage, like what the old version of the plugin once demonstrated: delimiters: ['<@', '@>'].
https://github.com/rollup/rollup-plugin-replace
Nevertheless since these kind of preprocessing is pretty rudimentary, care is always needed when adding replaced keys and when using them.