web-dev-qa-db-ja.com

babelが「this」を「undefined」に変換しないようにする方法(および「use strict」を挿入する方法)

[〜#〜] edit [〜#〜]:これは太い矢印ではなくです。また、this[〜#〜] iife [〜#〜]に渡すことでもありません。これは、トランスパイラーに関連した質問です。

そのため、作業中の小さなアプリ用のシンプルなpub-subを作成しました。私は、スプレッド/レストを使用し、頭痛を軽減するためにES6で書きました。私はそれをトランスパイルするためにnpmとgulpで設定しましたが、それは私を夢中にさせています。

ブラウザーライブラリーにしましたが、どこでも使用できることに気づいたので、CommonjsとAMDの互換性を持たせることにしました。

ここに私のコードのトリミングされたバージョンがあります:

_(function(root, factory) {
 if(typeof define === 'function' && define.AMD) {
    define([], function() {
        return (root.simplePubSub = factory())
    });
  } else if(typeof module === 'object' && module.exports) {
    module.exports = (root.simplePubSub = factory())
  } else {
    root.simplePubSub = root.SPS = factory()
  }
}(this, function() {
 // return SimplePubSub
});
_

しかし、(this変数を作成して渡すなど)私が何をしようとしても、undefined

_}(undefined, function() {
_

これはおそらく、Babelがthisが何であるかを知らず、それを変換することに関係していますが、私がとることができる他のアプローチはありますか?

[〜#〜] update [〜#〜]thisの代わりに}((window || module || {}), function() {を渡す作業。しかし、これが最善のアプローチであるかどうかはわかりません。

47
JR Halchak

Babel> = 7.xの場合

ES6コードには2つの処理モードがあります。

  • 「スクリプト」-<script>、またはファイルをロードする他の標準的なES5の方法でファイルをロードする場合
  • 「モジュール」-ファイルがES6モジュールとして処理される場合

Babel 7.xでは、ファイルはデフォルトで「モジュール」として解析されます。問題の原因は、ES6モジュールではthisundefinedであるのに対し、"script"の場合、windowのように環境によって異なることです。ブラウザースクリプトまたはCommonJSコードのexports。同様に、"module"ファイルは自動的に厳格なので、Babelは"use strict";を挿入します。

Babel 7では、この動作を回避する場合は、ファイルの種類をBabelに伝える必要があります。最も簡単なオプションは、 "sourceType" オプションを使用してBabelオプションにsourceType: "unambiguous"を設定することです。これは、基本的に、Babelに基づいてタイプ(スクリプトとモジュール)を推測するように指示しますimportおよびexportステートメントの存在。主な欠点は、importまたはexportを使用しないES6モジュールを使用することは技術的には問題ないことであり、これらはスクリプトとして誤って扱われます。一方、それは実際にはそれほど一般的ではありません。

または、Babel 7の "overrides" オプションを使用して、特定のファイルをスクリプトとして設定できます。

overrides: [{
  test: "./vendor/something.umd.js",
  sourceType: "script",
}],

どちらのアプローチでも、Babelはいくつかのファイルがscriptタイプであり、したがってthisundefinedに変換すべきではないことを知ることができます。

Babel <7.xの場合

ES6コードには2つの処理モードがあります。

  • 「スクリプト」-<script>、またはファイルをロードする他の標準的なES5の方法でファイルをロードする場合
  • 「モジュール」-ファイルがES6モジュールとして処理される場合

Babel 6およびbabel-preset-es2015(またはBabel 5)を使用する場合、Babelはデフォルトで、処理するファイルがES6モジュールであると想定します。問題を引き起こしているのは、ES6モジュールではthisundefinedであり、ファイルはすべて厳格であるのに対し、「スクリプト」の場合、thisは環境によって異なるため、ブラウザスクリプトのwindowやCommonJSコードのexportsなど。

Babelを使用している場合、最も簡単なオプションは、UMDラッパーなしでコードを記述し、Browserifyなどを使用してファイルをバンドルし、UMDラッパーを自動的に追加することです。 Babelはbabel-plugin-transform-es2015-modules-umdも提供します。両方とも単純化に向けられているため、カスタマイズされたUMDアプローチが必要な場合、それらはあなたには向かないかもしれません。

または、すべてのBabelプラグインを babel-preset-es2015 に明示的にリストし、モジュール処理babel-plugin-transform-es2015-modules-commonjsプラグインを必ず除外する必要があります。また、これはuse strictの自動追加も停止します。これはES6仕様の一部でもあるため、コードを自動的に厳格に保つためにbabel-plugin-transform-strict-modeを追加し直すことができます。

[email protected]現在、プリセットはオプションを取ることができます。

{
  "presets": [
    [ "es2015", { "modules": false } ]
  ]
}

babelの設定(.babelrc)で、モジュール処理を無効にしてbabel-preset-es2015を使用します。

60
loganfsmyth

「es2015」プリセットは、デフォルトでcommonJsラッパーにBabel出力をラップします。 「babel-preset-es2015-script」を使用します(npm install --save babel-preset-es2015-script最初)「スクリプト」(モジュールなし)の出力。これは、Babelを使用してまとめていた他のライブラリに大混乱を引き起こしていました。

プリセット: https://www.npmjs.com/package/babel-preset-es2015-script

2
user2503764