Reputation: 947
In Chrome, when you right-click a string on the console, you'll see "copy string as javascript literal" option. This is what I want to have now, in JavaScript.
For example, let's say I have the following text content:
console.log('hoge');
My question is, how can I get something below from the above?
"console.log('hoge');"
I want to do this because, I have a mega bytes of webpack-generated long JavaScript content, and for a reason I need to eval()
the script on an other environment, so I want to copy-and-paste the JavaScript literal text to inside the "eval()". (you may suggest exchanging the data not with the literal but with json (json.stringify/parse), I know, but I just prefer the literal way for now)
So is it possible? Thanks.
Upvotes: 4
Views: 2269
Reputation: 113984
I have an app for this: https://www.npmjs.com/package/make-it-a-string
You can install it by simply using npm install -g
. Yes, I'm abusing npm to distribute apps but npm is the best cross-platform app store/repo I know of.
The code to convert anything to a valid javascript string is very simple. My app is just 15 lines long (see https://github.com/slebetman/make-it-a-string/blob/main/make-it-a-string).
I'm basically just doing this:
const valid_string = JSON.stringify(raw_string,null,4)
Yes, that's JSON.stringify()
. I'm abusing the fact that a string is valid JSON. Basically the string:
hello world
Has the JSON representation of:
"hello world"
And JSON.stringify()
knows how to add the quotes. As an added bonus, JSON.stringify()
also knows how to escape all other things that need escaping.
For example, the string:
hello
"world"
Has the JSON representation of:
"hello\n\"world\""
And again, JSON.stringify()
knows how to handle this. All the string encoding you need to convert some random string into a valid js string are fully specified by the JSON standard so JSON.stringify()
is in my humble opinion the correct and valid way to encode js strings.
My full code simply uses the clipboardy
module to read the text from and then write the formatted text to the clipboard. Here's the full code in case you don't feel like installing it from npm:
async function main () {
const clipboard = (await import('clipboardy')).default;
function result (x) {
clipboard.writeSync(x);
console.log(x);
}
let raw = clipboard.readSync();
result(JSON.stringify(raw,null,4));
}
main();
Obviously there's a chicken-and-egg problem here. To get the string you first need it in a js variable. And if it's already in a variable there's no reason to need it as a string. That's the whole reason I read it from the clipboard.
If instead of the clipboard you prefer to process the string from a file you can do it like this:
let raw = fs.readFileSync('my-source-text.js', 'utf8');
console.log(JSON.stringify(raw,null,4));
Upvotes: 0
Reputation: 17
It feels like you have done it already. You can write that to a file like so
fs.writeFileSync(file,
"console.log('hoge');"
);
or
fs.writeFileSync(file,
`
${ console.log('hoge')}
;`
)
back ticks are usually for multiline spacing
Upvotes: -1
Reputation: 1416
You can easily enclose Javascript in backticks to get a template literal:
eval(`console.log('hoge')`)
But you should also escape backticks inside the Javascript code to handle situations like this:
eval(`console.log(`hoge`)`) // SyntaxError
As a solution, you can use this bash one-liner:
sed 's/`/\\`/g' | xargs -0 printf 'eval(`%s`)'
Enter
.Enter
again.Ctrl+D
to finish input.eval()
function call with escaped template literal on the output.You can assign this one-liner command to an alias for easy use:
alias js_eval_literal="sed '"'s/`/\\`/g'"' | xargs -0 printf '"'eval(`%s`)'"'"
Upvotes: -1
Reputation: 2687
After noting the advice regarding the security weakness inherent in using eval
(see: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval)
You can achieve what you want by enclosing the entire literal code inside back-ticks and using the resulting string as the eval
argument. back tick quotted strings can include line breaks so you should be able to pass your entire code block inside a single set.
Working snippet.
console.log('hoge');
console.log('another hoge');
eval(`console.log('hoge');
console.log('another hoge')`);
Upvotes: 2