.packed.js で Template literals が正しく扱われない件の回避策
by
unarist
2017-04-02 [2017/04/02 04:08:08]
TL;DR: ` のすぐ内側に " or ' を入れる。内部でそれらを使う時はエスケープ。
-
/*
* @title .packed.js で Template literals が正しく扱われない件の回避策
* @description TL;DR: ` のすぐ内側に " or ' を入れる。内部でそれらを使う時はエスケープ。
* @license MIT License
* @javascript_url
*/
/* === まとめ ===
* バッククォートのすぐ内側に " or ` を入れる
(ES5的にはそれらによる文字列リテラル、ES6的にはTemplate literalになる)
* 同じ引用符をテンプレート内で使いたい時はエスケープする
(ES5的には必要なエスケープ、ES6的にはあっても困らないエスケープになる)
(プレースホルダで文字列リテラルを使う時はエスケープできないので、もう片方の引用符で)
* 改行もそのまま書いてOK
(ES5的にはNGだけどJavaScript::Squishは通る、ES6的にはTemplate literal内なので)
(ちなみに .packed.js でも改行がそのまま出力される。@javascript_url では %0D%0A に変換される。)
* 余分な引用符の存在は Template literal の評価に影響を与えないので、
評価後に .slice(1, -1) するだけでよい。
*/
{
let LET_ID = "foo";
alert(`'<div class="${LET_ID}" onclick="alert(\'test\')">
</div>'`.slice(1, -1));
}
// 最初は ` と ' を入れ替える方法がいいかと思ったけど、
// リテラル内の改行が使えなかったので却下。
// (JavaScript::Squish は通るんだけども)
/*
function template(def) {
return eval(def.toString().replace(/['`]/g, c => ({"'": "`", "`": "'"})[c]));
}
let divTemplate = template(x => '<div class="${x.LET_ID}" onclick="alert(`test`)"></div>');
let result = divTemplate({LET_ID: "hoge"});
*/
// その流れでこうなったけど、評価後にsliceするだけなら関数通す必要もない
// ということで冒頭の形に。まあ好みで。
/*
function template(def) {
return function(){ return def.apply(this, arguments).slice(1, -1); };
}
{
let divTemplate = template(x => `'<div class="${x.LET_ID}" onclick="alert(\'test\')"></div>'`);
alert(divTemplate({LET_ID: "hoge"}));
let divTemplate2 = (template(() => `'<div class="${LET_ID}" onclick="alert(\'test\')"></div>'`));
let LET_ID = "piyo";
alert(divTemplate());
}
*/
-
- Permalink
- このページへの個別リンクです。
- RAW
- 書かれたコードへの直接のリンクです。
- Packed
- 文字列が圧縮された書かれたコードへのリンクです。
- Userscript
- Greasemonkey 等で利用する場合の .user.js へのリンクです。
- Loader
- @require やソースコードが長い場合に多段ロードする Loader コミのコードへのリンクです。
- Metadata
- コード中にコメントで @xxx と書かれたメタデータの JSON です。