- browserify
- webpack
- rollup
なんぞ
前提認識
- モジュール化されてないプログラムはつらい
- JSにはモジュール化の仕組みはない
話はNode.js界に遡る
経緯
- Node.jsは、モジュール化の仕組みとしてrequireを用意している
- 外部のJSをモジュールとして読み込める
使い方1
-
node_modules/
下にインストールした「Standard Modules」を読み込む
var Vue = require("vue");
//もう使えるぞ
new Vue({})
# 使い方2
mylib.js
module.exports = function(a, b){
return a + b
}
var myLib = require("./mylib");
var result = myLib(1, 1);
// -> 2
module.exports?
- ここにオブジェクトを突っ込むと外部に公開される
- それ以外の変数は隠蔽される
シングルトンとして使う
ストアオブジェクトなんかを作れる
var a = require("./mylib");
var b = require("./mylib");
a.message = "hoge";
console.log(a.message);
console.log(b.message);
hoge
hoge
Node.jsだけじゃなくてブラウザでも使いたい
- npmエコシステムに乗りたい
require()はブラウザにはない
- ない
- evalを使うと無限に脆弱性が生まれる
- あと、fsとかhttpみたいなNode.jsにしかないAPIを使ってるモジュールは当然動かない
browserify
- ブラウザにJSから外部JSを読み込む仕組みはない
- じゃあrequireで呼ばれた全JSをくっつけて一枚にしようぜ
- Node.jsのAPIも一応ブラウザで動くようにする
bundle.js
$ browserify main.js -o bundle.js
- requireをすべてconcatで解決(力技)
- bundle.jsができる(でかい)
多少でかくても最近の人は気にしない
webpackも大体いっしょ
ES6 Import
ES6 Import
- requireみたいなやつを標準化しようとしてできた
- 非同期読み込みの効率化、内部の隠蔽など…
- 静的解析に強くなるらしい
- TypeScriptの型チェックやrollupのTree shakingでは重要
- 詳しくはよくわからん
Nodeのrequire互換の書き方
var lib = require("./lib");
ES6
import * as lib from "./lib"
ES6 Classと使う
import {MyClass} from "./lib"
new MyClass().hello();
export class MyClass{
hello(){
console.log("hey");
}
}
問題点:Edge以外誰も対応してない
requireにコンバートすればとりあえず動くのでは…
- Babel, TypeScriptはES6 Importをrequireに変換できる
- requireに変換したあとはbrowserifyかwebpackでconcatすればブラウザで動く
- 単体でもbundle化可能だったかも?やったことはないが・・・
ここまでする必要あんの
- 「JSをビルドする」のが常態化
- モジュールバンドラ使わなくてもscriptタグで読みこめばええやん的な話はある
- scriptタグで読み込んだものはすべてグローバルなので、その辺が許せればいいんでは
- 自分の立場:TypeScriptみたいに、ビルドついでに型チェックのようなオマケがつくなら積極的にやりたい