質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
ECMAScript

ECMAScriptとは、JavaScript類の標準を定めるために作られたスクリプト言語です。

Babel

Babelは、JavaScriptの次世代仕様であるECMAScriptのコンパイラ。次世代の標準機能を用いて記述されたコードを、それらの機能に対応していないブラウザでも動作するコードに変換することができます。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

解決済

1回答

5985閲覧

Babelでコンパイルすると文字化けする

退会済みユーザー

退会済みユーザー

総合スコア0

ECMAScript

ECMAScriptとは、JavaScript類の標準を定めるために作られたスクリプト言語です。

Babel

Babelは、JavaScriptの次世代仕様であるECMAScriptのコンパイラ。次世代の標準機能を用いて記述されたコードを、それらの機能に対応していないブラウザでも動作するコードに変換することができます。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

0クリップ

投稿2016/11/30 15:53

編集2016/11/30 15:54

utf-8で参考書を写経しましたが、Babelでコンパイルして実行すると下記の様に文字化けします。'佐藤真央'を``で囲むと回避できました。すごい初歩的なことなのかもしれませんが、理由がよくわかりません。

値は佐藤真央

function hoge(value) { return new Promise((resolve, reject) => { setTimeout(() => { if (value) { resolve(`値は${value}`); } else { reject('値が空です'); } }, 2000); }); } hoge('佐藤真央').then( response => { console.log(response); }, error => { console.log(error); } );

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

Babelの問題では無く、JavaScriptを呼び出す環境の問題です。この現象を説明するにはソースファイルの文字コードとBabelの変換の動作の両方について知る必要があります。

###JavaScriptのソースファイルの文字コードについて

JavaScriptではソースファイル(.jsのファイル)の文字コードに関する規定がありません。JavaScriptでの文字列(string)はUnicodeコードポイントとして解釈され、内部ではUTF-16で管理されますが、ソースファイル自体がどの文字コードであるかは仕様で定められていません。

参考: ECMAScript® 2016 Language Specification #11.8.4String Literals

ある文字コードのソースファイルをUnicodeコードポイントに変換するのはJavaScriptエンジンの仕事です。そして、どの文字コードとして読み込むのかを決めるのもJavaScriptエンジンが行います。これは使い方やエンジンの種類によって異なります。

####HTMLから使用するJavaScript

HTMLのscript要素でsrc属性を使って読み込んだ場合は、デフォルトではHTML自身の文字コードになります。また、script要素のcharset属性で任意の文字コードに指定できます。

参考: HTML 5.1: 4.12. Scripting #4.12.1.1. Processing model より(訳は私訳)

If the <script> element has a charset attribute, then let encoding be the result of getting an encoding from the value of the charset attribute.
<script>要素がcharset属性を持つ場合、charest属性の値に基づいてエンコードする。

If the <script> element does not have a charset attribute, or if getting an encoding failed, let encoding be the same as the encoding of the document itself.
<script>要素がcharset属性持たない、または、文字コードの取得に失敗する場合、文書(訳注: HTML自身のこと)それ自体と同じ文字コードでエンコードする。

もし、HTMLについて<meta charset="UTF-8">等で文字コードを指定せずに、UTF-8で書いていた場合、ブラウザによっては文字化けします。同様のことがHTMLから使用されるJavaScriptにも言えます。HTMLで指定している文字コードとJavaScriptが一致しない場合は、charset属性を正しく設定しない限り、文字化けします。

注意して欲しいのはASCIIの部分は文字化けしないことです。一部の特殊な文字コードを除き、主流の文字コードはASCIIと互換性があり、ASCIIのみであれば文字化けすることはありません。次の注意点としてUnicodeエスケープ(\uXXXXや\u{XXXXXX}という表現)も文字化けしません。これはASCIIのみで表現されており、正しくJavaScriptの内部表現であるUTF-16になるため、ソースファイルの文字コードが何であるかという影響を受けないからです。

####ブラウザではなくJavaScriptエンジンで直接実行した場合。

node.js(内部はV8)の場合はUTF-8を前提にするようです。※ 正式な文章は見つけられませんでした。

WSH(JScript)はたしかWindows上のロケール依存だったと思います。日本語環境であればWindows31-J(Shift_JISの亜種、別名CP932)になると思われます。※ 手元ですぐに試せないので、未検証です。

SpiderMonkeyは調べてません。ごめんなさい。

###Babelでの変換でのUnicodeエスケープ

さて、Babelではどうなのか、囲み方の違いによってなぜ違うのか、を説明します。Babelで変換を行う場合、通常はnode.jsを使います。ですので、UTF-8のソースファイルを正しく解釈してくれます。しかし、"(二重引用符)の囲みと`(逆引用符)の囲みでは動作が異なります。

JavaScript

1var a_dq = "あ"; 2var a_bq = ``;

をBabelで変換すると

JavaScript

1var a_dq = "あ"; 2var a_bq = "\u3042";

になります。二重引用符の場合はそのままです。特に何も加工しません。しかし、逆引用符の場合は、Unicodeエスケープに変換されてしまいます。詳しく内部を確認しないとはっきりは言えませんが、逆引用符の場合は${...}という所に特殊な処理が必要ですので、一度、JavaScriptとしてのUTF-16文字列として完全に読み込み、${...}を除いたそのまま表示する部分を通常の文字列として書き込んでいるのだと思われます。このとき、ASCII文字以外は元の文字コードで直接表現可能かがわからないため、Unicodeエスケープで表現しているのだと思われます。(推測です)

このように表現が変わりました。前半で、Unicodeエスケープ文字はソースファイルの文字コードに影響を受けないと話したと思います。そうです。間違った文字コードが指定されてJavaScriptが読み込まれたとき、a_dq(二重引用符)のところは文字化けしてしまいますが、a_bq(逆引用符)の所は文字化けを起こしません。これが動きが違うように見えた原因です。


以上になります。対応としては、JavaScriptの文字コードを正しく指定することです。UTF-8なのに文字化けと言うことは、HTMLからの使用だと思われますが、HTMLもUTF-8にして、<meta charset="UTF-8">を指定することが一番いい方法だと思います。

投稿2016/11/30 22:26

raccy

総合スコア21733

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2016/12/01 13:06 編集

ご回答ありがとうございます。 おっしゃる通りでhtmlにエンコード記述入ってないし、ブラウザはエンコード自動検出、babelでコンパイルしたjsファイル自体は文字化けなしでした。また、Unicodeエスケープに関しても勉強になりました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問