JSPMで始めるWEB開発


jspmはSystemJSをローダーとした、ライブラリ管理、Transpile、パッケージングを一つにまとめたシステムの事。
Webpackみたいなもん。

ウィザード的な使い方ではなく、一般的な利用方法を説明。
迷わないように、気にしなくても良い部分は割愛。

jspmインストール

npm install -g jspm
npm install jspm --save-dev

jspmの初期化

jspm init

jspmのセットアップ。設定ファイルの中身をインタラクションで作成してくれる。
以下は全てデフォルトで指定した時の中身。

System.config({
  baseURL: "/",
  defaultJSExtensions: true,
  transpiler: "babel",
  babelOptions: {
    "optional": [
      "runtime",
      "optimisation.modules.system"
    ]
  },
  paths: {
    "github:*": "jspm_packages/github/*",
    "npm:*": "jspm_packages/npm/*"
  },
  map: {
    色々書いてる。
  }
}

JSPM 設定ファイルについて

baseURL

baseURLは、SystemJSがファイルをロードする際の基準となるhttpのパス

baseURLが「/foo」で

import 'path/hoge'

とした場合に、合成されたパスは「http://xx.xx.xx.xx/foo/path/hoge.js」となる。
(なぜ拡張子がjsになるかは後程)

Babelオプション

Transpilerとなるbabelのオプションで、ES7のデコレータ機能を有効にするには以下の様にする。

babelOptions: {
  "optional": [
    "runtime",
    "optimisation.modules.system",
    "es7.decorators"
  ]
},
paths

pathsの設定は、デフォルトのパスが気に入らない限りは変更しなくても良い。
意味としては[npm:][github:]で始まるパスを変換する為のルールづけ。

変更したい場合は[package.json]のjspmに

  "jspm" {
    "directories": {
      "packages": "配置したいパス"
    }
  }

と設定し[jspm init]を呼び出すと、新しいパスに配置してくれる。
pathsを変更しても、jspmコマンドを呼ぶたびに上書きされるので無駄!

map

mapの中身は基本的に気にしなくても良い。jspm install等でどんどん変更されていく。

jspmでのライブラリ管理

Clientサイドのライブラリは全てjspmで管理

jspm install <packagename>

基本的には、jspmが管理しているリポジトリからの導入となる。
ただ、npmで管理されているライブラリはほぼ全て導入可能。
その場合は「jspm install npm:」とする。

githubの物も利用できるが、場合によっては導入に多少の修正が必要な事も。
ちなみに「jspm install github:

開発時にのみ必要なライブラリは[--dev]オプションを利用する。

インストールされたPackage等は、package.jsonの「jspm」以下に記録されている。

jspmでのBundlePackage作成

jspm bundle-sfx <application main js path> <output js file path> --minify

gulpとProcessHtml

ProcessHtml

Bundle時とそうではない場合で、読み込むScriptを変える必要があるので、それをPrcessHtmlに処理させる。

エントリーポイントとなるjsは[main.js]で、Bundle後の名前が[main.bundle.js](bundle-sfx)とした場合。

Bundle前

<script src="jspm_packages/system.src.js"></script>
<script src="config.js"></script>
<script>
  System.import("./main.js");
</script>

Bundle後

  <script src="./main.bundle.js"></script>


ProcessHtmlでBundle後に切り替えさえる。

<!-- build:remove -->
<!-- This part will be delete in product version -->
<script src="jspm_packages/system.src.js"></script>
<script src="config.js"></script>
<script>
  System.import("./main.js");
</script>
<!-- /build -->
<!-- build:template
  <script src="./main.bundle.js"></script>
/build -->


こうする事で、Bundle前はProcessHtml前の物を読み、Bundle後はProcessHtml後の物を読むようにすればよい。

Gulp

必要npmパッケージ(yargsはおまけ)

    "gulp": "^3.9.1",
    "gulp-jspm": "^0.5.8",
    "gulp-processhtml": "^1.1.0",
    "gulp-sourcemaps": "^1.6.0",
    "yargs": "^4.6.0"

以下はサンプル。gulp-jspmを利用している。(minifyが無いので自分でやってね)

var gulp = require('gulp')
var yargs = require('yargs').argv
var gulp_jspm = require('gulp-jspm')
var sourcemaps = require('gulp-sourcemaps')
var processhtml = require('gulp-processhtml')
var processopts = { /* plugin options */ }

gulp.task('default', [ 'build' ])

gulp.task('bundle' , function () {
  return gulp.src(<main.jsをピックアップするように設定>)
    .pipe(sourcemaps.init())
    .pipe(gulp_jspm({selfExecutingBundle: true})) // `jspm bundle-sfx main`
    .pipe(sourcemaps.write('.'))
    .pipe(gulp.dest('build/'))
})

gulp.task('processHtml', function () {
  return gulp.src(<index.htmlをピックアップするように設定>)
    .pipe(processhtml(processopts))
    .pipe(gulp.dest('build/'))
})

gulp.task('build', [ 'bundle', 'processHtml' ])

jspmで作るWebページのテンプレ

reactを利用する目的で、divを一つ配置している。

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>テンプレート</title>
</head>

<body>
  <div id="root"></div>
</body>

<!-- build:remove -->
<!-- This part will be delete in product version -->
<script src="jspm_packages/system.src.js"></script>
<script src="config.js"></script>
<script>
  System.import("./main.js");
</script>
<!-- /build -->
<!-- build:template
  <script src="./main.bundle.js"></script>
/build -->

</html>

main.jsのおまけテンプレート

import 'jquery'

$(function () {
  //DO SOMETHING
})