export defaultはなぜ急に役に立たなかったのですか?


前言
先日、チームの仲間から質問がありました.tsファイルで解構を使って変数を導出しました.他の場所でimport入ってみるとundefinedというように
//a.ts
export const a = {
   a1: 1,
   a2: 2
}

export const b = {
    b1: 1
}

export default {
 ...a,
 b
}
// b.ts
import { a1 } from 'a';
console.log(a1): // undefined

ここで疑問を投げ出すの?
使用していたのにbabel-plugin-add-module-exports互換していたexport default、でも取れなかった?
次に、export defalut->babel->add-module-exportsから、なぜかを徐々に理解します.
义齿export defaultモジュールのデフォルト出力を指定するコマンド.明らかに、1つのモジュールにはデフォルト出力が1つしかないため、export defaultコマンドは1回しか使用できません.本質的には、export defaultは、defaultという変数やメソッドを出力し、任意の名前を付けることができます.
このように関数をエクスポート
//a.js
export default funcion() {
   //xxx
}
//b.js
import foo from 'a';

オブジェクトのエクスポート
//c.js
const c = { c1:1, c2:2 }
const d = { d1:1, d2:2 }
export default {
    c,d
}
//d.js
import obj from 'c'
console.log(obj); // {c:{c1:1,c2:2},d:{d1:1,d2:2}}

defaultのエクスポート
//a.js
function foo(){}
export { foo as default};
//    
// export default foo;

// b.js
import { default as foo } from 'a';
//    
// import foo from 'a';

ここまですべてが美しく見えますが、新しい質問があります.d.jsで、直接objc属性を手に入れたいのですが、よろしいでしょうか.
const c = { c1:1, c2:2 }
const d = { d1:1, d2:2 }
export default {
    c,d
}
//d.mjs
import {c} from 'c'
console.log(c); //    

// terminal
node --experimental-modules d.js
/*
import {c} from 'c';
        ^
SyntaxError: The requested module 'c' does not provide an export named 'c'
*/

ES 6のimportはオブジェクト解構文法ではなく、見た目が似ているので、MDNのimportの説明MDN importを参照してください.したがってimportはdefaultオブジェクトを解体することはできません.
importがdefaultオブジェクトの解体をサポートしていない以上、私たちの心の中にはもう一つの疑問があります.なぜ私たちはプロジェクトでexport defaultを勝手に書くことができ、解体によって取ることができるのでしょうか.
export defaultコンパイル結果export defaultES 6に属する構文は、ES 6をサポートしないブラウザと互換性があるためbabelコンパイルが必要です.次にbabelコンパイル後、export default何になったかを見てみましょう.
babel 5時代
babel 5を使用する場合は、次のコードに従います.
//a.js
const a = {};
const b = {};
export default {a,b}
//b.js
import {a} from 'b'
console.log(a)

パッケージ化されます
//a.js
...
let _default = _objectSpread({}, {a, b});
exports.default = _default;
module.exports = exports.default;

//b.js
"use strict";
var _const = require("./a");
console.log(_const.a);

babelはesmをcjsに解析し、b.jsを実行し、値を取ることができることを発見したが、ブラウザ環境require文法では、webpackが必要だ.webpackは簡単に言えばbabel変換後のファイルにrequireの包装をしたので、ここではwebpackが何をしたのかは具体的には話さず、babelだけを議論し、webpackが具体的に何をしたのかはここで調べることができる.
Webpack起動コード解読
Webpackモジュール化原理
babel 6時代
プロジェクトがbabel 6をアップグレードした後、前の書き方が値を取れないことに気づいて、上のa.jsとb.jsは梱包してから
//a.js
...
let _default = _objectSpread({}, {a, b});
exports.default = _default;
// babel6     module.exports = exports.default;

//b.js
"use strict";
var _const = require("./a");
console.log(_const.a);

このとき_constの値は{default: {a:{},b{}}}です.これは、BabelのこのIssueKill CommonJS default export behaviourのため、Babel 6が実行しなくなったmodule.exports = exports['default']モジュール変換によって動作が変更されたためである.Babel 5はexportをサポートするオブジェクトですが、Babel 6になるとこの特性は削除されます.このとき我々は古いコードと互換性を持つために解決策が必要で、このときbabel-plugin-add-module-exports入場しました.
babel-plugin-add-module-exports入場babel-plugin-add-module-exportsBabel 6から取り除くmoduleを補うのが主な役割である.exports = exports.default; 質問ですが、プロジェクトに配置されていますbabel-plugin-add-module-exportsなぜ最前線のコードに問題があるのでしょうか
babel-plugin-add-module-exports失効原因
答えは簡単で、babel-plugin-add-module-exportsが失効したことを発見し、ソースコードに深くロゴを打つとname exportがあるかどうかを判断し、name exportがあればbabel 5 export default objectの特性を補うことはありません.
// hasExportNamed     true
...
if (hasExportDefault &&  !hasExportNamed) {

path.pushContainer('body', \[types.expressionStatement(types.assignmentExpression('=', types.memberExpression(types.identifier('module'), types.identifier('exports')), types.memberExpression(types.identifier('exports'), types.stringLiteral('default'), true)))\]);

}
...

ソリューション:コードを変更するだけで
//a.ts
const a = {
   a1: 1,
   a2: 2
}
const b = {
    b1: 1
}
export default {
 ...a,
 b
}
// b.ts
import { a1 } from 'a';
console.log(a1): // 1

私たちはexport constを削除し、export defaultだけを残してこの問題を解決する必要があります.
なぜname exportがあれば、補完しないのかと好奇心のある同級生が聞くmodule.exports = exports.default.次の例を見ればわかります
//a.ts
export const a = {
   a1: 1,
   a2: 2
}
const b = {
    b1: 1
}
export default {
 b
}
// b.ts
import { a } from 'a';
console.log(a);

梱包後手動で1個module.exports = exports.default
//a.js
...
let _default = _objectSpread({}, {b});
exports.default = _default;
module.exports = exports.default;

その結果、bファイルrequireが入ってきたとき、aが見つからなかったことがわかります.
//b.js
"use strict";
var _const = require("./a");
console.log(_const.a); // undefined

締めくくりexport default協力babel-plugin-add-module-exports開発体験を良くしてくれましたが、守らなければなりませんexport defaultの基本ルール:es6 export default導出した内容はツールがありますがes6 import解法ではありません.なお、デフォルト出力のあるモジュールを導入する場合、importコマンドの後にカッコを使用せずに、導入した内容を解体しないでください.
ヘルプリンク:
import、require、export、moduleについて.exports