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

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

ただいまの
回答率

90.35%

  • JavaScript

    22087questions

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

  • ECMAScript

    149questions

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

  • Babel

    80questions

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

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

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 1,570

masuo

score 263

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);
  }
);
  • 気になる質問をクリップする

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

+4

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のソースファイルを正しく解釈してくれます。しかし、"(二重引用符)の囲みと`(逆引用符)の囲みでは動作が異なります。

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

をBabelで変換すると

var a_dq = "あ";
var 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/12/01 21:16 編集

    ご回答ありがとうございます。

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

    キャンセル

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

  • ただいまの回答率 90.35%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る

  • JavaScript

    22087questions

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

  • ECMAScript

    149questions

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

  • Babel

    80questions

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