PHP->JSの変換は実践的に使える!?

PHPがJSに変換できる!?

babel-preset-phpというのが出たそうです。
Qiitaで見ました->PHP って JavaScript に変換できるの?できるわけないだろ! babel-preset-php ってのが今日リリースされた?これまさか・・・。ファーーーーーーーーーーーwwwwwwwwwwww
相変わらず長いタイトルです…
いやでもこれはすごい!確かにすごい!

CrayonHighlighterのコードが変換したい

かねてから変換したいなーと思っていました
aramk/crayon-syntax-highlighter
もともとWordPress向けで、WPであればプラグインをインストールするだけで使えます
Readmeにも書いてある通り、PHPであればどんな環境でも使えます
その使い方については別記事に書きます!
enter image description here
こんなのをブログに埋め込める
報告程度なので詳細は省きます!

変換!

重要そうなファイルはcrayon_~.phpってやつで、wpが入ってないやつだと思うんだ(適当)(気軽にPHP試せる環境がない…)

変換をしただけだがエラーが…

例えばこれをトランスパイルすると
test.php
class Hoge{
    function fuga($x){
        self::$bar[$x];
    }
}
以下のエラーが
TypeError: file.php: Got a MemberExpression for MemberExpression property
    at Generator.MemberExpression (略)
何言ってるかわからないというか、何のエラーかわからない。
コメントアウトを駆使して、二分探索でエラーの原因コードを突き詰めたのが、上のtest.phpというわけです。
以下のように修正すればトランスパイルは通ります
class Hoge{
    function fuga($x){
        self::$bar->$x;
        // もしくは
        (self::$bar)[$x];
    }
}
たぶんこれで対応可能なので、自動で変換してみたい
ちょっと勘違いしかけたのが、self::barself::$barは同じコードになるけど、PHPでは定数かstatic変数か、の違いがあること
(基本を結構忘れてるな…)
self::bar[$x]は変換できたけど、
self::$bar[$x]は変換できなかったから、たぶんpresetのバグかなぁ…(parentとおなじ挙動にしようとしているとか?)

変換

/(self::\w+)(\[.*\];)/g($1)$2に変換
自動化するプログラムを書こうと思ったけど、
VSCodeのプロジェクト内の置換が使えそう
enter image description here

ごめん足りてなかった、

/(self::\w+)(\[\$\w+\])/g
素直にこうしとけばok

とおもったけど

これ左辺値に来たらだめだから、
/(self::\w+)\[(\$\w+)\]/g->$1->$2
にします(;´・ω・)
そしたら置換して保存

作業

まずすべてのファイルをrequireで橋渡しをしてあげないといけません
が、そのまえに…

クラス内の静的変数って作れるんですかね…?

static変数に変換されててめんどい。
メソッドだけじゃないですかね…
これはもうTypeScript解釈してトランスパイルした方が早そう…
あと複数行コメントがきれいに変換されないケースがありますね…
メンバのコメントがすべてクラスに付与されるからですかね…
これはIssueを出しときますか

躓く…

いろいろある。
  • コメントがうまく変換されない
  • static変数は使えない
  • $(予約語)
など。予約語は置換でアンダースコアを手前に挟んで対応
static変数はtypescriptで対処するとして、
結局コメントがうまく変換されないのが一番つらい
もとのPHPからコメントを除去しようにも、
VSCodeでやろうとすると改行をうまく扱えなくて、
(.|.)とかいうパターンを書いてたらVSCode落ちたww
なかなかつらいですね…(´・ω・`)

NodeJSで処理自動化

結局、楽。
const fs = require('fs')
const glob = require('glob')

glob('src/**/*.php', (err, files)=>{
  if(err)throw err
  files.forEach(file => {
    let path = file.toString()
    let data = fs.readFileSync(path).toString()
    data = data
      .replace(/(^|[\n\r]{1,2})\s*\/\/.*([\n\r]{1,2}|$)/g, "\n")
      .replace(/\/\*(?:[^\/*]|\*(?!\/)|\/(?!\*))*\*\//g, "\n")
      .replace(/(self::\$\w+)(\[.+\];)/g, "($1)$2")
      .replace(/(self::\$\w+)\[(\$\w+)\]/g, "$1->$2")
      .replace(/\$default\b/g, "$_default")
      .replace(/\$var\b/g, "$_var")
    fs.writeFileSync(path, data)
    console.log("finished : " + path)
  })
})
一行コメントと複数行コメントは別に除去してるよ
微調整は手打ちでやろうかなーと思ったけど、
全部自動でできるようにRegExpのほうを微調整してしまった( ´ー`)フゥー
(ここに一番時間がかかってしまった…ふぇえ…)

さらに問題発生

メンバ関数とstatic変数が被る。
うっそだろーーー!!!!と。
でもWPの機能なのでバッサリ切って、
と作業をしていけばどうにか完成する感じですかね…

WordPressの関数の存在で分岐してる

うーんうーん、どうしよう

defineはglobal.~に変換しなきゃ

((+_+))うーん

これは…

作業ですね

やーめた!

PHP→NodeJSは目の前ともいえる素晴らしい発明、
babel-preset-phpにここでもう一度お礼申し上げます。
やはり、壁はPHPとNodeJSのモジュールシステムの差ですか…?
PHPもJSもスクリプト言語出身なだけあって、自由なところをなかなか上手に扱えないですね…
これからの開発に期待して待っていましょう!

感想

一個目のエラーはIssue出しといたほうがいいのかな…?
コメントが崩れるのはIssue出しておきました!
ファイル数は少ないんですけど、一個一個が結構ぎっしりしていて…
例えば一つのPHPファイルにまとめてしまうのは?などが現実的かなと思いました。
大学生になったときにもし気が向いたら、程度に考えておきます
(だれかやってくれないかなー|д゚)チラッ)
以上です!最後までありがとうございます!

このブログの人気の投稿

YouTube Iridiumの紹介

うくこん

TDPC - T フィボナッチ