.packed.js で Template literals が正しく扱われない件の回避策

  • /*
     * @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 です。

History

  1. 2017/04/02 04:08:08 - 2017-04-02
  2. 2017/04/01 12:52:32 - 2017-04-01
  3. 2017/04/01 12:50:28 - 2017-04-01
  4. 2017/04/01 12:47:54 - 2017-04-01