のぐそんブログ

暗いおじさんがシコシコ書くブログです。

webpack-dev-serverを使ってみる

webpack-dev-server

開発用サーバを立てることができるモジュールです。

詳しくは公式のドキュメントを見てみてください。

手順

モジュールをインストール。

npm install --save-dev webpack-dev-server

package.jsonにscriptを追加。

"scripts": {
      "start": "webpack-dev-server"
}

サーバーを起動する。

npm start

http://localhost:8080でアクセスできるようになる。

サーバーの設定をする

サーバーの設定は、package.jsonにも指定できるが、webpack.config.jsに記載すると見やすい気がする。

サーバーに設定できるオプションで、私がよく使うのは下記。

オプション 説明
contentBase サーバの起点ディレクトリを指定。未指定の場合はカレントディレクトリが起点になる。
port 未指定の場合は8080が初期値になる。
open サーバー起動時にブラウザを開く。true or falseで指定。
inline ライブリロードを行うための設定。true or falseで指定。未指定の場合はtrue
hot Hot Module Replacement(HMR)を有効にします。true or falseで指定。未指定の場合はtrue。

※hotについては、webpack.config.jsに指定するとエラーとなるのでpackage.jsonにwebpack-dev-server --hotとして渡す必要があるようです。

webpack.config.jsに指定する場合
  devServer: {
    contentBase: path.resolve(__dirname, 'dist'),
    port: 3000,
    open:true
  },
package.json指定する場合
"scripts": {
  "start": "webpack-dev-server client.js --inline --hot --colors --content-base dist/ --port=3000"
}

live reloadを利用する

ライブリロードを行う場合は、webpack.config.jsのoutputpathの設定と、devServercontentBaseの設定を同じにする必要があるようです。

ただし、同じにした場合に少し問題があります。 出力先のフォルダにindex.htmlを入れることになるので、ファイル構成上変な感じがします(私だけかもしれませんが。。。)

そこで、outputpublicPathを設定することで、pathcontentBaseが異なってもライブリロードを行うことができます。 publicPathはwebpack-dev-serverを利用する際は、指定したほうが良さそうです。

const path = require('path');

module.exports = {
  //ビルドするファイル
  entry: path.resolve(__dirname, './src/main.js'), 
  //ビルドしたファイルの出力先
  output: {
    path: path.resolve(__dirname, './dist'),
    filename: 'bundle.js',
    publicPath: '/assets'
  },
  //開発サーバーの設定
  devServer: {
    contentBase: path.resolve(__dirname, './src'),
    inline: true,
    open: true
  },
  devtool: 'source-map'
};

webpack-dev-serverでのビルド

webpack-dev-serverでも、webpack.config.js設定にあわせてファイルのビルドが行われます。 ただしこのビルドは、実際のnpm run buildとは異なり、ファイルはメモリ上に保存されます。

例)webpack.config.jsの設定が上記の場合はこんな感じ

.
├── node_modules
├── package-lock.json
├── package.json
├── src
│   ├── index.html
│   ├── main.js
│   └── assets //メモリ上に存在する
│        └── dist.js //メモリ上に存在する
└── webpack.config.js

その他

webpack-dev-serverはipはそのままの設定ではプライベートIPでアクセスすることができません。

プライベートIPでアクセスする為、host:0.0.0.0disableHostCheck: trueを追加します。

  devServer: {
    contentBase: path.resolve(__dirname, 'dist'),
    port: 3000,
    open:true,
    host 0.0.0.0,
    disableHostCheck: true
  },

まとめ

メモリ上にファイルが保存されるのがよくわからず、ハマりました。

THREE.jsのEffectComposerでオリジナルのポストプロセスをやってみる

前回「THREE.jsでオリジナルのポストプロセスをやってみる」と題しましてポストプロセスについての記事を書きました。

よくよく調べると、THREE.jsにはポストプロセスを行う仕組み自体が用意されており、それを利用すればオリジナルのポストプロセスも簡単に書くことができました。

やってみる

オリジナルのポストプロセスを行うには下記のファイルが必要です。

JS

ShaderPassにShaderMaterialと同じように、unfiforms、vertexShader、fragmentShaderを含んだオブジェクトを追加します。 uniformsには、通常のシーンの描画結果を入れるtDiffuseというテクスチャ型のオブジェクトが必ず必要です。

以下の例では、ポストプロセスで通常のシーンのUV座標をずらすエフェクトをかけています。

var renderer,
    scene,
    camera,
    myCanvas = document.getElementById('myCanvas');

//RENDERER
renderer = new THREE.WebGLRenderer({
    canvas: myCanvas,
    antialias: true
});
renderer.setClearColor(0xffffff);
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);

//CAMERA
camera = new THREE.PerspectiveCamera(30, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.z = 1;

//SCENE
scene = new THREE.Scene();

//LIGHTS
var light = new THREE.AmbientLight(0xffffff, 0.5);
scene.add(light);

var material = new THREE.MeshLambertMaterial();
var geometry = new THREE.SphereGeometry(0.1, 20, 20);
var mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);


//ポストプロセスの設定
//WebGLRendererをラップするためにEffectComposerに渡す
//最終的にはEffectComposerのインスタンスを描画する
var composer = new THREE.EffectComposer(renderer);
//現在のシーンを設定
var renderPass = new THREE.RenderPass(scene, camera);
composer.addPass(renderPass);
//カスタムシェーダー
var myEffect = {
    uniforms: {
        "tDiffuse": {
            value: null,
            type: 't'
        },
        "amount": {
            value: 1.0,
           type:'f'
        }
    },
    vertexShader: [
        "varying vec2 vUv;",
        "void main() {",
        "vUv = uv;",
        "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );",
        "}"
    ].join("\n"),
    fragmentShader: [
        "uniform float amount;",
        "uniform sampler2D tDiffuse;",
        "varying vec2 vUv;",
        "void main() {",
        "vec4 color = texture2D( tDiffuse, vUv );",
        "gl_FragColor = vec4( color.rgb , color.a );",
        "gl_FragColor.r = texture2D( tDiffuse, vUv + vec2(0.1,0.0)).r;",
        "gl_FragColor.g = texture2D( tDiffuse, vUv - vec2(0.1,0.0)).g;",
        "}"
    ].join("\n")
}

//エフェクト結果をスクリーンに描画する
var customPass = new THREE.ShaderPass(myEffect);
customPass.renderToScreen = true;
composer.addPass(customPass);

render();


function render() {

    composer.render();

    requestAnimationFrame(render);
}

まとめ

THREE.EffectComposerを使うと、オフスクリーンレンダリング明示的にやらなくてよかったり、画面全体を覆うポリゴンを作る必要がなかったりとポストプロセスを行う上で手間がかからない印象でした。 また、ShaderMaterialを使わなくてもシェーダーを定義することができるので、ライトをつかえるなど私のような初心者にはメリットが多そうでした。

THREE.jsでオリジナルのポストプロセスをやってみる

前回オフスクリーンレンダリングについて書きました。

今回は、オフスクリーンレンダリングを利用して、ポストプロセスをやってみたいと思います。

ポストプロセスを簡単に言うと、作成済みのシーンに対して、あとから何か処理を行うことです。

今回は以下のような2つのシーンを掛け合せてみようと思います。

続きを読む