Underscore: WebPackはrequire( 'underscore')を誤ってエミュレートします

作成日 2020年05月25日  ·  9コメント  ·  ソース: jashkenas/underscore

今日1.9.2から1.10.2にアップデートしましたが、 require('underscore');を使用するとミックスインが機能しなくなりました

これはTypeError: _.camelcase is not a function失敗します:

const _ = require('underscore');
const underscoreString = require('underscore.string');

_.mixin(underscoreString.exports());

console.log(_.camelcase('foo-bar'));

しかし、これは機能します:

import _ from 'underscore';
const underscoreString = require('underscore.string');

_.mixin(underscoreString.exports());

console.log(_.camelcase('foo-bar'));

invalid

全てのコメント9件

@dmaicher、これがあなたを噛んでいると聞いて申し訳ありません。 ただし、Underscore1.10.2およびunderscore.string3.3.5ではこれを再現できません。 セットアップについて何か特別なことはありますか?

迅速な返信ありがとうございます:blush:

[email protected]を使用していますが、ブラウザにバンドルされているコードで問題が発生します。 CLIでノードを使用してコードを実行すると、問題がないように見えます:confused:

最小限の再現機能は次のとおりです: https

ここにあなたの問題があります:

https://github.com/dmaicher/underscore_issue_2852/blob/348eef226ec7392b2ced2b92ddf2fcba2517ab5c/public/build/app.js#L13

そのインポートパスunderscore/modules/index-all.js 、WebPackがpackage.jsonmoduleフィールドから取得している必要があります。

https://github.com/jashkenas/underscore/blob/5d8ab5e37c9724f6f1181c5f95d0020815e4cb77/package.json#L17 -L18

一方、CommonJSインポートを使用している場合、 mainフィールドを使用する必要があります。 moduleは、それらをサポートするツールへのESインポート用であり、 mainは他のすべてのユーザー用です。 これは、コードがimportが、 require()では機能しない理由を説明しています。

どうやら、最近のWebPackはデフォルトでESモジュールを想定していますが、CommonJSインポートのフォールバックがあります。 ESモジュールを想定しないように、またはmoduleフィールドを無視するように、何らかの方法で構成する必要があると思います。 または、ESモジュールに切り替えたい場合もあります。

これはアンダースコアの問題ではなくWebPackの問題であるため、これを終了します。 ただし、コメントを続けてください。

@jgonggrijpチェックしてくれてありがとう:+1:

webpack設定で解決するためのエイリアスを追加することで修正できました:
'underscore': 'underscore/underscore.js',

しかし、これは私には少し奇妙に思えます。 私が指定する使用する多くの他のパッケージ"main""module"自分の内側にpackage.jsonと彼らのためにそれがうまく動作します。

Webpackは、最初に見つかったフィールドを['browser', 'module', 'main']順序で取得します
https://webpack.js.org/configuration/resolve/#resolvemainfieldsを参照して

アンダースコアでのみ失敗するのに、他のパッケージでは機能しているように見えるのはなぜか知りたいです:blush:

これらの他のパッケージに名前を付けていただければ幸いです。 とにかく、 modulemainは互換性があることを意図していないので、WebPackがそれらをそのように扱うことは保証されていません。

https://github.com/rollup/rollup/wiki/pkg.module

リンクしたドキュメントは、 resolve.mainFields['main']に設定するという、おそらく少し醜い解決策を示唆しています。 繰り返しになりますが、CommonJSインポートを使用しているので、WebPackはそもそもmoduleを考慮すべきではないと思います。

関連するwebpackの問題: https

はい、それはあなたの問題です。 moduleに解決するときにWebPackがCommonJSをエミュレートする方法にも問題があるようですが。 次のようなことをしているようです。

// converting modules/index-all.js to ES3
var underscoreESModule = {
    'default': _,
    map: _.map,
    filter: _.filter,
    // ...
};
// in your code that imports underscore
var _ = underscoreESModule;

後者の行は、これを実行している場合に意味があります。

import * as _ from 'underscore';

しかし、実際に行っていることはこれと同等です。

import _ from 'underscore';

それをWebPackでES3に変換する正しい方法は次のとおりです。

var _ = underscoreESModule['default'];

これは、他の人がwebpack / webpack#5756で遭遇している問題でもあります。

BrowserifyやRollupなどの他のビルドツールは、これをよりインテリジェントに処理します。 ただ言って...

このページは役に立ちましたか?
0 / 5 - 0 評価