- Contents -
Cloud9 を使って angular2 の開発を始めてみよう。
すんなり行くはずだったけど、ng serve
してもうまく外部アクセスできなかった。
いろいろ迷走するなか、うまくいく手順が分かったので記載しておきます。
Cloud9 環境を用意する。
Cloud9 の環境を用意しよう。
環境はBlank (Ubuntu)を選択してワークスペースを作成すると良い。
こういう使い捨ての環境が簡単につくれるのは本当にありがたい。
nodejsの更新
ワークスペースが準備できたら、早速必要なものをインストール。
すでに、初期段階でnvm (Node Version Manager) がインストールされている。
しかし、デフォルトのNodeバージョンは古い。
$ node --version
v4.6.1
Angular2 は node6以降でないと動作しないので、バージョンアップしておく必要がある。
nvmを使えば、最新node のインストールも簡単だ。
-- 追記 --
$ node --version
v6.11.2
2017年12月現在であれば、
デフォルトで入っているNodeバージョンは6になっているみたいですね。
なので、nodejsの更新はしなくてもOKです。
nvm の使い方
nvm help
Usage:
nvm help Show this message
nvm --version Print out the latest released version of nvm
nvm install [-s] <version> Download and install a <version>, [-s] from source. Uses .nvmrc if available
--reinstall-packages-from=<version> When installing, reinstall packages installed in <node|iojs|node version number>
nvm uninstall <version> Uninstall a version
nvm use [--silent] <version> Modify PATH to use <version>. Uses .nvmrc if available
nvm exec [--silent] <version> [<command>] Run <command> on <version>. Uses .nvmrc if available
nvm run [--silent] <version> [<args>] Run `node` on <version> with <args> as arguments. Uses .nvmrc if available
nvm current Display currently activated version
nvm ls List installed versions
nvm ls <version> List versions matching a given description
nvm ls-remote List remote versions available for install
nvm version <version> Resolve the given description to a single local version
nvm version-remote <version> Resolve the given description to a single remote version
nvm deactivate Undo effects of `nvm` on current shell
nvm alias [<pattern>] Show all aliases beginning with <pattern>
nvm alias <name> <version> Set an alias named <name> pointing to <version>
nvm unalias <name> Deletes the alias named <name>
nvm reinstall-packages <version> Reinstall global `npm` packages contained in <version> to current version
nvm unload Unload `nvm` from shell
nvm which [<version>] Display path to installed node version. Uses .nvmrc if available
最新の安定版をインストール
# stableバージョンをインストール
nvm install stable
# Shellを起動し直すと、また古い方のNodeが使用されるので、
# デフォルトNodeを設定しておく。
nvm alias default stable
Downloading https://nodejs.org/dist/v7.10.0/node-v7.10.0-linux-x64.tar.xz...
######################################################################## 100.0%
Now using node v7.10.0 (npm v4.2.0)
default -> stable (-> v7.10.0)
Nodeのバージョンにあわせて、npmのバージョンも更新されている。
Angular-CLI
Angular2 プロジェクトを作成するなら、
CLI からプロジェクトのテンプレート作成するのがよい。
angular-cli のインストール
npm install -g @angular/cli
ng コマンドが使えるようになっている。
プロジェクト作成
ngコマンドを使ってプロジェクトを作成
ng new MyApp
Successfully initialized git.
Installing packages for tooling via npm.
のあと、しばらく止まったように見えるが、
npm install
が走っているのでしばらく待ちましょう。
完了すると、下記のようにcreatedと出力されるぞ。
Installed packages for tooling via npm.
Project 'MyApp' successfully created.
実行してみる。
本来なら、以下のコマンドで終わりかと思っていたが、
起動はするもののCloud9のPreviewアドレスからアクセスできない。。
npm run start
> my-app@0.0.0 start /home/ubuntu/workspace/MyApp
> ng serve
** NG Live Development Server is listening on localhost:8080, open your browser on http://localhost:8080 **
Hash: 398a066707b4bb1df2d0
Time: 17738ms
chunk {0} polyfills.bundle.js, polyfills.bundle.js.map (polyfills) 157 kB {4} [initial] [rendered]
chunk {1} main.bundle.js, main.bundle.js.map (main) 3.63 kB {3} [initial] [rendered]
chunk {2} styles.bundle.js, styles.bundle.js.map (styles) 10.5 kB {4} [initial] [rendered]
chunk {3} vendor.bundle.js, vendor.bundle.js.map (vendor) 2.4 MB [initial] [rendered]
chunk {4} inline.bundle.js, inline.bundle.js.map (inline) 0 bytes [entry] [rendered]
webpack: Compiled successfully.
curlでローカルからアクセス curl localhost:8080
してみると、
正常にレスポンスが返ってくるので、外部からアクセスできない模様。
--host=0.0.0.0 を付けて起動すれば良いという記事も見つけたが、
今度は Invalid Host Header... というエラーが出てしまったり・・・
解決方法
参考URL
- https://github.com/webpack/webpack-dev-server/issues/882
- http://stackoverflow.com/questions/43619644/i-am-getting-an-invalid-host-header-message-when-running-my-react-app-in-a-we
- http://stackoverflow.com/questions/43677629/invalid-host-header-in-when-running-angular-cli-development-server-c9-io
いろいろ、調べてみたが、
対応方法は以下の3つのどれかを行えば良さそう。
-- 追記 --
最後の方に、追記いたしました。
ng serve に --public-host オプションを指定して実行する事ができますので、
これらの解決方法は不要となりました。
解決法1 Server.js を、書き換える。
node_modules/webpack-dev-server/lib/Server.js のcheckHost関数で
return trueを返すようにするというもの。
一番手っ取り早いが、ライブラリを直接書き換えるので、何か無理矢理感が否めない。
node_modules/webpack-dev-server/lib/Server.js
Server.prototype.checkHost = function(headers) {
// allow user to opt-out this security check, at own risk
if(this.disableHostCheck) return true;
// get the Host header and extract hostname
// we don't care about port not matching
const hostHeader = headers.host;
if(!hostHeader) return false;
const idx = hostHeader.indexOf(":");
const hostname = idx >= 0 ? hostHeader.substr(0, idx) : hostHeader;
// always allow localhost host, for convience
if(hostname === "127.0.0.1" || hostname === "localhost") return true;
// allow hostname of listening adress
if(hostname === this.listenHostname) return true;
// also allow public hostname if provided
if(typeof this.publicHost === "string") {
const idxPublic = this.publicHost.indexOf(":");
const publicHostname = idxPublic >= 0 ? this.publicHost.substr(0, idxPublic) : this.publicHost;
if(hostname === publicHostname) return true;
}
// disallow
return false;
}
解決法2 disableHostCheck: true に設定する。
webpack.config.js で、disableHostCheck: true という設定をする。
こっちは試してないが、
解決法1と同じで、Server::checkHost 関数が無条件でtrueを返すようになる。
解決法3 --public オプションでホスト名をちゃんと指定する。
正しいpublicホストを指定してやる。
ng serve
によるサーバー起動では、publicホストの指定ができないので、以下の手順が必要。
# ng server コマンドではなく、webpackコマンドを使うように変更する。
ng eject
# package.json が更新されるので、再度インストール。
npm install
==========================================================================================
Ejection was successful.
To run your builds, you now need to do the following commands:
- "npm run build" to build.
- "npm run test" to run unit tests.
- "npm start" to serve the app using webpack-dev-server.
- "npm run e2e" to run protractor.
Running the equivalent CLI commands will result in an error.
==========================================================================================
Some packages were added. Please run "npm install".
webpack.config.js も生成される。
package.json を編集する。
--public で指定しているホストは、自身のCloud9のホスト名を指定する。
package.json
@@ -4,7 +4,7 @@
"scripts": {
"ng": "ng",
- "start": "webpack-dev-server --port=4200",
+ "start": "webpack-dev-server --port=8080 --host=0.0.0.0 --public=angular2-workspace-tyabuta.c9users.io",
"build": "webpack",
"test": "karma start ./karma.conf.js",
おしまい
これでCloud9でAngular2 開発ができるぞ!!
npm run start
> my-app@0.0.0 start /home/ubuntu/workspace/MyApp
> webpack-dev-server --port=8080 --host=0.0.0.0 --public=angular2-workspace-tyabuta.c9users.io
10% building modules 3/3 modules 0 activeProject is running at http://angular2-workspace-tyabuta.c9users.io/
webpack output is served from /
~ 省略 ~
webpack: Compiled successfully.
Preview > Preview Running Application
追記
コメントいただきました。
ありがとうございました。
2017年12月時点で試してみると、確かにng serveコマンドにpublic オプションを渡して実行できるようです。
バージョンは以下の通り。
$ ng --version
Angular CLI: 1.6.2
Node: 6.11.2
OS: linux x64
Angular: 5.1.2
... animations, common, compiler, compiler-cli, core, forms
... http, language-service, platform-browser
... platform-browser-dynamic, router
@angular/cli: 1.6.2
@angular-devkit/build-optimizer: 0.0.36
@angular-devkit/core: 0.0.22
@angular-devkit/schematics: 0.0.42
@ngtools/json-schema: 1.1.0
@ngtools/webpack: 1.9.2
@schematics/angular: 0.1.11
@schematics/schematics: 0.0.11
typescript: 2.4.2
webpack: 3.10.0
一応、ng serve のヘルプも記載します。
$ ng help
ng serve <options...>
--port (Number) (Default: 8080) Port to listen to for serving.
aliases: -p <value>, -port <value>
--host (String) (Default: localhost) Listens only on localhost by default.
aliases: -H <value>, -host <value>
--public-host (String) Specify the URL that the browser client will use.
aliases: --live-reload-client <value>, --publicHost <value>
--public-host じゃなくて、--publicでもOKでした。
package.json
"start": "ng serve --port=8080 --host=0.0.0.0 --public-host=angular2-workspace-tyabuta.c9users.io",
これで、npm run start
するだけでいけます。
Cloud9 のポートについて
ちなみに、portは指定しなくても、デフォルトで8080ポートで起動します。
Cloud9 では、8080ポートが公開ポートとして動作します。
https://angular2-workspace-tyabuta.c9users.io -> OK
https://angular2-workspace-tyabuta.c9users.io:8080 -> OK
https://angular2-workspace-tyabuta.c9users.io:80 -> NG
URLのポートを省略した場合でも、8080ポートに繋がっているようです。
こんにちは。とてもありがとうございます。助かりました!私が試したところ、ng serveはpublicオプションを受け付けてくれました。Angularのバージョンは4.2.4でした。
コメントありがとうございました。
ng serve の publicオプションについて、追記させてもらいました。