【メモ】Google Closure Compilerを使う

【メモ】Google Closure Compilerを使う:


Google Closure Compilerとは?

https://developers.google.com/closure/compiler/
https://github.com/google/closure-compiler

JavaScriptをJavaScriptに変換するコンパイラー。コードをより効率的な形に変換してくれる。ClojureScriptが使っていたりする。

その昔は独自のモジュールシステムを持っていたのだが、いつのまにかnpm経由で使えるようになっていたり、nodeモジュールに対応していたり、いろいろ進歩している模様。


package.json

{ 
    "name": "teach-yourself-closure-compile", 
    "version": "1.0.0", 
    "scripts": { 
        "build": "..." 
   }, 
    "dependencies": { 
        "immutable": "^4.0.0-rc.12", 
        "luxon": "^1.8.2", 
        "react": "^16.6.3", 
        "react-dom": "^16.6.3" 
    }, 
    "devDependencies": { 
        "@babel/cli": "^7.2.0", 
        "@babel/core": "^7.2.0", 
        "@babel/preset-react": "^7.0.0", 
        "babel-loader": "^8.0.4", 
        "cpx": "^1.5.0", 
        "google-closure-compiler": "^20181210.0.0", 
        "rimraf": "^2.6.2" 
    } 
} 
今回はReactでごく簡単なサンプルを作り、動作させることを目標とする。ついでなのでいくつかライブラリーを入れてみる。

ビルド手順は後述。


index.jsx

index.jsx
const React = require("react") 
const ReactDOM = require("react-dom") 
const ImMap = require("immutable/dist/immutable").Map 
const DateTime = require("luxon/build/node/luxon").DateTime 
 
class Application extends React.Component { 
 
    constructor(props) { 
        super(props); 
        this.state = { date: DateTime.local().toISO() } 
    } 
 
    componentDidMount() { 
        this.timer = setInterval(() => this.setState({ date: DateTime.local().toISO() }), 500) 
    } 
 
    componentWillUnmount() { 
        clearTimeout(this.timer) 
    } 
 
    render() { 
        return ( 
            <div> 
                <h1>hello, closure compiler!</h1> 
                <p>User: {this.props.user.get("firstName")} {this.props.user.get("lastName")}</p> 
                <p>Current date: {this.state.date}</p> 
            </div> 
        ) 
    } 
} 
 
ReactDOM.render( 
    <Application user={ImMap({ firstName: "John", lastName: "Smith" })} />, 
    document.getElementById("app") 
) 
どうもデフォルトインポートをうまく扱えないようで断念。requireでロードする。

またpackage.jsonの指定ファイルを見てくれないのか、require("immutable")ではだめで、require("immutable/dist/immutable")とファイルのパスを指定する必要があった。

immutable.jsのMapImMapにリネームしているのは、バインディングが重複しているというエラーが出たため。


ビルド


Babel

まずJSXを普通のJSに変換する。ここではBabelを使用。

.babelrc
{ 
    "presets": [ 
        "@babel/preset-react" 
    ], 
    "compact": false, 
    "comments": true 
} 
babel src --out-dir ./out/babel 


コンパイル

google-closure-compiler --js out/babel/index.js --js node_modules/react --js node_modules/react-dom/index.js --js node_modules/react-dom/cjs/react-dom.production.min.js --js node_modules/react-dom/cjs/react-dom.development.js  --js node_modules/object-assign --js node_modules/prop-types --js node_modules/scheduler --js node_modules/luxon/build/node/luxon.js --js node_modules/immutable/dist/immutable.js --entry_point out/babel/index.js --js_output_file out/closure/index.js --module_resolution NODE --dependency_mode LOOSE --process_common_js_modules --language_in ECMASCRIPT_NEXT 
--jsフラグで入力ファイルを指定。見てのとおり、モジュールもすべて指定する必要がある。そんなわけないだろうと思うのだが、それらしいオプションを発見できず断念。知っている方教えてください。

--entry_pointでコンパイルを始めるエントリーポイントを指定する。今回はBabelでコンパイルされたファイルを指定。

--js_output_fileは出力先。

--module_resolution NODE --process_common_js_modulesでnodeモジュールを使っていることを伝える。

--language_in ECMASCRIPT_NEXTでECMAスクリプトバージョンを指定する。

フラグ一覧はこちら


その他

  • React DevToolsが動かなかった。これは悲しい。
  • ライブラリーもコンパイルされるので、警告が大量に出力される。--warnings_whitelist_fileフラグでホワイトリストファイルを作ればよさそうだが、さすがに面倒くさすぎる。
  • 今回のソースのリポジトリはこちら

コメント

このブログの人気の投稿

投稿時間:2021-06-17 05:05:34 RSSフィード2021-06-17 05:00 分まとめ(1274件)

投稿時間:2021-06-20 02:06:12 RSSフィード2021-06-20 02:00 分まとめ(3871件)

投稿時間:2020-12-01 09:41:49 RSSフィード2020-12-01 09:00 分まとめ(69件)