node.js製CMS「Apostorophe」を試す


この記事は J2complexed Advent Calendar 2016 の17日目の記事です。
遅れました。
だんだん書くことがなくなってきたので、引き出しの中から引っ張りだしてきます。


ほとんどWordpress一強の時代が長く続いているようなCMS界ですが、ほかにも星の数ほどCMSはあるので、いろいろ試してみるのもよいのかもしれませんですね。

フロントエンだーとしては、フロントで完結できるCMSならば、さくっといけるんではないかと思ったりするので、そんなこんなでnode.js製の「Apostorophe」をちょっと触ってみました。

Apostorophe

  • node.js + mongoDB 製のCMS
  • テンプレートエンジンはNunjucks
    (つよそう / Heavily inspired by jinja2 らしい)
  • 管理画面がなく、ログイン後に、ページや要素に対して直接編集・追加していくスタイル。
    (リテラシー低くても編集できそうでよい)

よさそうなところ

  • 管理画面がないので、編集時にどこに何が反映されるか直感的でわかりやすい
  • テンプレート構築さえしてしまえば、更新の敷居は低そう(スライドショーなど機能も最初から組み込まれてる)
  • 公式のドキュメントが充実(英語力が試される / つらい)
  • (インストールとかは公式が丁寧なので試したい方はぜひこちらを)

うーむなところ

  • 国内海外含めて開発者が多くはない(日本語の情報ほとんどなさそう)
  • テンプレートエンジンがNunjucksといえど、ちょっと癖があるので公式ドキュメントを頼るしかない
  • デフォルトがlessなので、gulpとかでごにょごにょしないとsassが使えない
  • versionが2.0になった結果、前のversionと仕様が変わってるので、web上にある情報が使えなかったりする。 (公式のgithub issueでsass使いたいよー!っていうのに回答しているのとか、v2.0では動かないみたい)

そういうわけで、gulpをごにょごにょする

  • sass使いたい
  • node.jsいちいち再起動するの面倒くさい
  • ので、gulp + sass(+browser-sync)で使えるようにする

積極的にgulpfileを晒していく。

gulpfile.js

var gulp = require('gulp'),
    nodemon = require('gulp-nodemon'),
    concat = require('gulp-concat'),
    sass = require('gulp-sass'),
    pleeease = require('gulp-pleeease'),
    bulkSass = require('gulp-sass-bulk-import'),
    header = require('gulp-header'),
    plumber = require('gulp-plumber'),
    notifier = require('node-notifier'),
    uglify = require('gulp-uglify'),
    sequence = require('run-sequence'),
    util = require('gulp-util'),
    neat = require('node-neat').includePaths,
    rename = require('gulp-rename'),
    notify = require('gulp-notify'),
    path = require('path'),
    browserSync = require('browser-sync');

var reloadDelay = 1000;

gulp.task('sass', function() {
  console.log('-------------------- sass')

  return gulp.src('lib/modules/apostrophe-assets/public/css/style.scss')
    .pipe(sourcemaps.init())
    .pipe(plumber({errorHandler: notify.onError('<%= error.message %>')}))
    .pipe(bulkSass())
    .pipe(sass())
    .pipe(pleeease({
      fallbacks: {
        autoprefixer: ['ie 9']
      },
      minifier: true
    }))
    .pipe(rename(function(path) {
      path.dirname = "lib/modules/apostrophe-assets/public/css/";
      path.basename = "style";
      path.extname = ".less"
    }))
    .pipe(gulp.dest('./'));
});

gulp.task('watch', function() {
  console.log('-------------------- watch')
  gulp.watch('lib/modules/apostrophe-assets/public/css/**/*.scss', ['sass']);
});

gulp.task('nodemon', function (cb) {
  var called = false;
  return nodemon({
    script: 'app.js',
    ext: 'html js',
    watch: ["views/", "lib/modules/apostrophe-assets/public/css/*", "app.js", "lib/"],
  })
    .on('start', function onStart() {
    if (!called) { cb(); }
    called = true;
  })
    .on('change', ['sass'])
    .on('restart', function () {
    console.log('restarting');
    setTimeout(function reload() {
      browserSync.reload({
        stream: false
      });
    }, reloadDelay);
  })
});

gulp.task('browser-sync', ['nodemon'], function () {
  var port = process.env.PORT || 3000;
  browserSync.init({
    files: ['public/**/*.*'],
    proxy: 'http://localhost:' + port, 
    port: 4000,
    open: false
  });
});

gulp.task('default', function (done) {
  sequence('browser-sync', 'watch', done);
});

$ gulp
でwatchします。

やっていることは、

  • scssファイルをwatchして、変更があったら1つのファイルにまとめて、.less拡張子に変換
  • ファイルに変更があったら、node.jsのapp.jsを更新(ここで、gulpから吐き出されたlessファイルをcssに変換したり)
  • brower-syncでビューを更新

ファイルパス等々、環境によって違うことがあるので、ご参考までに!

もうちょっと調べて実用レベルまで持ってきたいなー、とふわふわした状態のポエムになってしまいました。
ほかも良さそうなCMSあるか調査中。to be continued ...