@atlaspack/babel-plugin-transform-contextual-imports 2.13.2-canary.3683 → 2.13.2-canary.3684

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/index.js CHANGED
@@ -13,6 +13,9 @@ $parcel$defineInteropFlag(module.exports);
13
13
 
14
14
  $parcel$export(module.exports, "default", () => $35f0bedee55d5f76$export$2e2bcd8739ae039);
15
15
 
16
+ const $35f0bedee55d5f76$var$isServer = (opts)=>{
17
+ return 'server' in opts && opts.server;
18
+ };
16
19
  const $35f0bedee55d5f76$var$isNode = (opts)=>!!('node' in opts && opts.node);
17
20
  var $35f0bedee55d5f76$export$2e2bcd8739ae039 = (0, $b65XQ$babelhelperpluginutils.declare)((api)=>{
18
21
  const { types: t } = api;
@@ -55,11 +58,51 @@ var $35f0bedee55d5f76$export$2e2bcd8739ae039 = (0, $b65XQ$babelhelperpluginutils
55
58
  ])
56
59
  ]))
57
60
  ];
61
+ const buildServerObject = (identUid, cond, ifTrue, ifFalse)=>[
62
+ // Create object containing imports
63
+ t.variableDeclaration('const', [
64
+ t.variableDeclarator(t.identifier(identUid), t.objectExpression([
65
+ t.objectProperty(t.identifier('ifTrue'), t.memberExpression(t.callExpression(t.identifier('require'), [
66
+ ifTrue
67
+ ]), t.identifier('default'))),
68
+ t.objectProperty(t.identifier('ifFalse'), t.memberExpression(t.callExpression(t.identifier('require'), [
69
+ ifFalse
70
+ ]), t.identifier('default')))
71
+ ]))
72
+ ]),
73
+ // Create lazy getter via the load property on the object
74
+ t.expressionStatement(t.callExpression(t.memberExpression(t.identifier('Object'), t.identifier('defineProperty')), [
75
+ t.identifier(identUid),
76
+ t.stringLiteral('load'),
77
+ t.objectExpression([
78
+ t.objectProperty(t.identifier('get'), t.arrowFunctionExpression([], t.conditionalExpression(t.logicalExpression('&&', t.memberExpression(t.identifier('globalThis'), t.identifier('__MCOND')), t.callExpression(t.memberExpression(t.identifier('globalThis'), t.identifier('__MCOND')), [
79
+ cond
80
+ ])), t.memberExpression(t.identifier(identUid), t.identifier('ifTrue')), t.memberExpression(t.identifier(identUid), t.identifier('ifFalse')))))
81
+ ])
82
+ ]))
83
+ ];
84
+ const checkIsServer = (path, state)=>{
85
+ if (path.node.callee.type === 'Identifier' && path.node.callee.name === 'importCond') {
86
+ if (path.node.arguments.length == 3 && path.node.arguments.every((arg)=>arg.type === 'StringLiteral')) {
87
+ const [cond, ifTrue, ifFalse] = path.node.arguments;
88
+ if ($35f0bedee55d5f76$var$isServer(state.opts)) {
89
+ // Make module pass lazy in ssr
90
+ const identUid = path.scope.generateUid(`${cond.value}$${ifTrue.value}$${ifFalse.value}`);
91
+ state.importNodes ??= [];
92
+ state.importNodes.push(...buildServerObject(identUid, cond, ifTrue, ifFalse));
93
+ // Replace call expression with reference to lazy object getter
94
+ path.replaceWith(t.memberExpression(t.identifier(identUid), t.identifier('load')));
95
+ }
96
+ }
97
+ }
98
+ };
58
99
  return {
59
100
  name: '@atlaspack/babel-plugin-transform-contextual-imports',
60
101
  visitor: {
61
102
  CallExpression: {
62
103
  enter (path, state) {
104
+ // Preserve server behaviour in deletable code
105
+ checkIsServer(path, state);
63
106
  const node = path.node;
64
107
  if (isImportCondCallExpression(node)) {
65
108
  const [cond, ifTrue, ifFalse] = node.arguments;
@@ -102,6 +145,10 @@ var $35f0bedee55d5f76$export$2e2bcd8739ae039 = (0, $b65XQ$babelhelperpluginutils
102
145
  enter (_, state) {
103
146
  state.conditionalImportIdentifiers = new Set();
104
147
  state.visitedIdentifiers = new Set();
148
+ },
149
+ exit (path, state) {
150
+ if (state.importNodes) // If there's an import node, add it to the top of the body
151
+ path.unshiftContainer('body', state.importNodes);
105
152
  }
106
153
  }
107
154
  }
package/lib/index.js.map CHANGED
@@ -1 +1 @@
1
- {"mappings":"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","sources":["packages/utils/babel-plugin-transform-contextual-imports/src/index.ts"],"sourcesContent":["import type {PluginObj, NodePath, types as BabelTypes} from '@babel/core';\nimport {declare} from '@babel/helper-plugin-utils';\n\ninterface Opts {\n // Use node safe import cond syntax\n node?: boolean;\n}\n\ninterface State {\n opts: Opts;\n // Set of identifier names that need to be mutated after import was transformed\n conditionalImportIdentifiers?: Set<string>;\n // Set of identifiers that have been visited in the exit pass, to avoid adding the load property multiple times\n visitedIdentifiers?: Set<BabelTypes.Identifier>;\n}\n\nconst isNode = (opts: Opts): boolean => !!('node' in opts && opts.node);\n\nexport default declare((api): PluginObj<State> => {\n const {types: t} = api;\n\n const isImportCondCallExpression = (\n node: BabelTypes.Node,\n ): node is BabelTypes.CallExpression & {\n arguments: [\n BabelTypes.StringLiteral,\n BabelTypes.StringLiteral,\n BabelTypes.StringLiteral,\n ];\n } => {\n if (\n node.type === 'CallExpression' &&\n node.callee.type === 'Identifier' &&\n node.callee.name === 'importCond'\n ) {\n if (\n node.arguments.length === 3 &&\n node.arguments.every(\n (arg): arg is BabelTypes.StringLiteral =>\n arg.type === 'StringLiteral',\n )\n ) {\n return true;\n } else {\n // Simple error for incorrect syntax (since it's documented with the type)\n throw new Error('importCond must have three string literal arguments');\n }\n }\n\n return false;\n };\n\n const buildCondFunction = (\n cond: BabelTypes.StringLiteral,\n ifTrue: BabelTypes.StringLiteral,\n ifFalse: BabelTypes.StringLiteral,\n ) =>\n t.conditionalExpression(\n t.logicalExpression(\n '&&',\n t.memberExpression(t.identifier('globalThis'), t.identifier('__MCOND')),\n t.callExpression(\n t.memberExpression(\n t.identifier('globalThis'),\n t.identifier('__MCOND'),\n ),\n [cond],\n ),\n ),\n t.memberExpression(\n t.callExpression(t.identifier('require'), [ifTrue]),\n t.identifier('default'),\n ),\n t.memberExpression(\n t.callExpression(t.identifier('require'), [ifFalse]),\n t.identifier('default'),\n ),\n );\n\n const buildNodeObject = (\n identifier: BabelTypes.Identifier,\n cond: BabelTypes.StringLiteral,\n ifTrue: BabelTypes.StringLiteral,\n ifFalse: BabelTypes.StringLiteral,\n ) => [\n // Create object containing imports\n t.variableDeclaration('const', [\n t.variableDeclarator(\n identifier,\n t.objectExpression([\n t.objectProperty(\n t.identifier('ifTrue'),\n t.memberExpression(\n t.callExpression(t.identifier('require'), [ifTrue]),\n t.identifier('default'),\n ),\n ),\n t.objectProperty(\n t.identifier('ifFalse'),\n t.memberExpression(\n t.callExpression(t.identifier('require'), [ifFalse]),\n t.identifier('default'),\n ),\n ),\n ]),\n ),\n ]),\n\n // Create lazy getter via the load property on the object.\n // This is node module resolution safe because each time the import is accessed, we re-evaluate the condition.\n t.expressionStatement(\n t.callExpression(\n t.memberExpression(\n t.identifier('Object'),\n t.identifier('defineProperty'),\n ),\n [\n identifier,\n t.stringLiteral('load'),\n t.objectExpression([\n t.objectProperty(\n t.identifier('get'),\n t.arrowFunctionExpression(\n [],\n t.conditionalExpression(\n t.logicalExpression(\n '&&',\n t.memberExpression(\n t.identifier('globalThis'),\n t.identifier('__MCOND'),\n ),\n t.callExpression(\n t.memberExpression(\n t.identifier('globalThis'),\n t.identifier('__MCOND'),\n ),\n [cond],\n ),\n ),\n t.memberExpression(identifier, t.identifier('ifTrue')),\n t.memberExpression(identifier, t.identifier('ifFalse')),\n ),\n ),\n ),\n ]),\n ],\n ),\n ),\n ];\n\n return {\n name: '@atlaspack/babel-plugin-transform-contextual-imports',\n visitor: {\n CallExpression: {\n enter(path, state) {\n const node = path.node;\n if (isImportCondCallExpression(node)) {\n const [cond, ifTrue, ifFalse] = node.arguments;\n if (!isNode(state.opts)) {\n // Replace the importCond call with a conditional require import, as a fallback for environments that don't support Atlaspack\n path.replaceWith(buildCondFunction(cond, ifTrue, ifFalse));\n }\n }\n },\n },\n VariableDeclaration: {\n enter(path, state) {\n if (isNode(state.opts)) {\n if (\n path.node.declarations.length === 1 &&\n path.node.declarations[0].type === 'VariableDeclarator' &&\n path.node.declarations[0].id.type === 'Identifier'\n ) {\n const importId = path.node.declarations[0].id;\n const call = path.node.declarations[0].init;\n\n // Mark identifier for object so we don't add the load property to it\n state.visitedIdentifiers?.add(importId);\n\n if (call && isImportCondCallExpression(call)) {\n const [cond, ifTrue, ifFalse] = call.arguments;\n\n // Replace with object containing imports and lazy getter, which allows us to load the correct import based on the condition at runtime\n path.replaceWithMultiple(\n buildNodeObject(importId, cond, ifTrue, ifFalse),\n );\n\n // Add identifier name to set so we can mutate all import usages in the exit pass\n state.conditionalImportIdentifiers?.add(importId.name);\n }\n }\n }\n },\n },\n Identifier: {\n exit(path, state) {\n const identifier = state.conditionalImportIdentifiers?.has(\n path.node.name,\n );\n if (identifier && !state.visitedIdentifiers?.has(path.node)) {\n // Add load property to the import usage\n const newIdentifer = t.identifier(path.node.name);\n path.replaceWith(\n t.memberExpression(newIdentifer, t.identifier('load')),\n );\n state.visitedIdentifiers?.add(newIdentifer);\n }\n },\n },\n Program: {\n enter(_, state) {\n state.conditionalImportIdentifiers = new Set();\n state.visitedIdentifiers = new Set();\n },\n },\n },\n };\n});\n"],"names":["declare","Opts","node","State","opts","conditionalImportIdentifiers","Set","visitedIdentifiers","BabelTypes","Identifier","isNode","api","PluginObj","types","t","isImportCondCallExpression","Node","CallExpression","arguments","StringLiteral","type","callee","name","length","every","arg","Error","buildCondFunction","cond","ifTrue","ifFalse","conditionalExpression","logicalExpression","memberExpression","identifier","callExpression","buildNodeObject","variableDeclaration","variableDeclarator","objectExpression","objectProperty","expressionStatement","stringLiteral","arrowFunctionExpression","visitor","enter","path","state","replaceWith","VariableDeclaration","declarations","id","importId","call","init","add","replaceWithMultiple","exit","has","newIdentifer","Program","_"],"version":3,"file":"index.js.map","sourceRoot":"../../../../"}
1
+ {"mappings":";;;;;;;;;;;;;;;AAqBA,MAAMY,iCAAWA,CAACP;IAChB,OAAO,YAAYA,QAAQA,KAAKH,MAAM;AACxC;AAEA,MAAMW,+BAASA,CAACR,OAAwB,CAAC,CAAE,CAAA,UAAUA,QAAQA,KAAKF,IAAI,AAAJA;IAElE,2CAAeH,CAAAA,GAAAA,qCAAAA,EAAQ,CAACc;IACtB,MAAM,EAACE,OAAOC,CAAPD,EAAS,GAAGF;IAEnB,MAAMI,6BAA6BA,CACjCf;QAQA,IACEA,KAAKoB,IAAI,KAAK,oBACdpB,KAAKqB,MAAM,CAACD,IAAI,KAAK,gBACrBpB,KAAKqB,MAAM,CAACC,IAAI,KAAK,cACrB;YACA,IACEtB,KAAKkB,SAAS,CAACK,MAAM,KAAK,KAC1BvB,KAAKkB,SAAS,CAACM,KAAK,CAClB,CAACC,MACCA,IAAIL,IAAI,KAAK,kBAGjB,OAAO;iBAEP,0EAAA;YACA,MAAM,IAAIM,MAAM;QAEpB;QAEA,OAAO;IACT;IAEA,MAAMC,oBAAoBA,CACxBC,MACAC,QACAC,UAEAhB,EAAEiB,qBAAqB,CACrBjB,EAAEkB,iBAAiB,CACjB,MACAlB,EAAEmB,gBAAgB,CAACnB,EAAEoB,UAAU,CAAC,eAAepB,EAAEoB,UAAU,CAAC,aAC5DpB,EAAEqB,cAAc,CACdrB,EAAEmB,gBAAgB,CAChBnB,EAAEoB,UAAU,CAAC,eACbpB,EAAEoB,UAAU,CAAC,aAEf;YAACN;SACH,IAEFd,EAAEmB,gBAAgB,CAChBnB,EAAEqB,cAAc,CAACrB,EAAEoB,UAAU,CAAC,YAAY;YAACL;SAAO,GAClDf,EAAEoB,UAAU,CAAC,aAEfpB,EAAEmB,gBAAgB,CAChBnB,EAAEqB,cAAc,CAACrB,EAAEoB,UAAU,CAAC,YAAY;YAACJ;SAAQ,GACnDhB,EAAEoB,UAAU,CAAC;IAInB,MAAME,kBAAkBA,CACtBF,YACAN,MACAC,QACAC,UACG;YACH,mCAAA;YACAhB,EAAEuB,mBAAmB,CAAC,SAAS;gBAC7BvB,EAAEwB,kBAAkB,CAClBJ,YACApB,EAAEyB,gBAAgB,CAAC;oBACjBzB,EAAE0B,cAAc,CACd1B,EAAEoB,UAAU,CAAC,WACbpB,EAAEmB,gBAAgB,CAChBnB,EAAEqB,cAAc,CAACrB,EAAEoB,UAAU,CAAC,YAAY;wBAACL;qBAAO,GAClDf,EAAEoB,UAAU,CAAC;oBAGjBpB,EAAE0B,cAAc,CACd1B,EAAEoB,UAAU,CAAC,YACbpB,EAAEmB,gBAAgB,CAChBnB,EAAEqB,cAAc,CAACrB,EAAEoB,UAAU,CAAC,YAAY;wBAACJ;qBAAQ,GACnDhB,EAAEoB,UAAU,CAAC;iBAGlB;aAEJ;YAED,0DAAA;YACA,8GAAA;YACApB,EAAE2B,mBAAmB,CACnB3B,EAAEqB,cAAc,CACdrB,EAAEmB,gBAAgB,CAChBnB,EAAEoB,UAAU,CAAC,WACbpB,EAAEoB,UAAU,CAAC,oBAEf;gBACEA;gBACApB,EAAE4B,aAAa,CAAC;gBAChB5B,EAAEyB,gBAAgB,CAAC;oBACjBzB,EAAE0B,cAAc,CACd1B,EAAEoB,UAAU,CAAC,QACbpB,EAAE6B,uBAAuB,CACvB,EAAE,EACF7B,EAAEiB,qBAAqB,CACrBjB,EAAEkB,iBAAiB,CACjB,MACAlB,EAAEmB,gBAAgB,CAChBnB,EAAEoB,UAAU,CAAC,eACbpB,EAAEoB,UAAU,CAAC,aAEfpB,EAAEqB,cAAc,CACdrB,EAAEmB,gBAAgB,CAChBnB,EAAEoB,UAAU,CAAC,eACbpB,EAAEoB,UAAU,CAAC,aAEf;wBAACN;qBACH,IAEFd,EAAEmB,gBAAgB,CAACC,YAAYpB,EAAEoB,UAAU,CAAC,YAC5CpB,EAAEmB,gBAAgB,CAACC,YAAYpB,EAAEoB,UAAU,CAAC;iBAInD;aAEL;SAEH;IAED,MAAMU,oBAAoBA,CACxBC,UACAjB,MACAC,QACAC,UACG;YACH,mCAAA;YACAhB,EAAEuB,mBAAmB,CAAC,SAAS;gBAC7BvB,EAAEwB,kBAAkB,CAClBxB,EAAEoB,UAAU,CAACW,WACb/B,EAAEyB,gBAAgB,CAAC;oBACjBzB,EAAE0B,cAAc,CACd1B,EAAEoB,UAAU,CAAC,WACbpB,EAAEmB,gBAAgB,CAChBnB,EAAEqB,cAAc,CAACrB,EAAEoB,UAAU,CAAC,YAAY;wBAACL;qBAAO,GAClDf,EAAEoB,UAAU,CAAC;oBAGjBpB,EAAE0B,cAAc,CACd1B,EAAEoB,UAAU,CAAC,YACbpB,EAAEmB,gBAAgB,CAChBnB,EAAEqB,cAAc,CAACrB,EAAEoB,UAAU,CAAC,YAAY;wBAACJ;qBAAQ,GACnDhB,EAAEoB,UAAU,CAAC;iBAGlB;aAEJ;YAED,yDAAA;YACApB,EAAE2B,mBAAmB,CACnB3B,EAAEqB,cAAc,CACdrB,EAAEmB,gBAAgB,CAChBnB,EAAEoB,UAAU,CAAC,WACbpB,EAAEoB,UAAU,CAAC,oBAEf;gBACEpB,EAAEoB,UAAU,CAACW;gBACb/B,EAAE4B,aAAa,CAAC;gBAChB5B,EAAEyB,gBAAgB,CAAC;oBACjBzB,EAAE0B,cAAc,CACd1B,EAAEoB,UAAU,CAAC,QACbpB,EAAE6B,uBAAuB,CACvB,EAAE,EACF7B,EAAEiB,qBAAqB,CACrBjB,EAAEkB,iBAAiB,CACjB,MACAlB,EAAEmB,gBAAgB,CAChBnB,EAAEoB,UAAU,CAAC,eACbpB,EAAEoB,UAAU,CAAC,aAEfpB,EAAEqB,cAAc,CACdrB,EAAEmB,gBAAgB,CAChBnB,EAAEoB,UAAU,CAAC,eACbpB,EAAEoB,UAAU,CAAC,aAEf;wBAACN;qBACH,IAEFd,EAAEmB,gBAAgB,CAChBnB,EAAEoB,UAAU,CAACW,WACb/B,EAAEoB,UAAU,CAAC,YAEfpB,EAAEmB,gBAAgB,CAChBnB,EAAEoB,UAAU,CAACW,WACb/B,EAAEoB,UAAU,CAAC;iBAKtB;aAEL;SAEH;IAED,MAAMY,gBAAgBA,CACpBC,MACAE;QAEA,IACEF,KAAK/C,IAAI,CAACqB,MAAM,CAACD,IAAI,KAAK,gBAC1B2B,KAAK/C,IAAI,CAACqB,MAAM,CAACC,IAAI,KAAK,cAE1B;YAAA,IACEyB,KAAK/C,IAAI,CAACkB,SAAS,CAACK,MAAM,IAAI,KAC9BwB,KAAK/C,IAAI,CAACkB,SAAS,CAACM,KAAK,CAAEC,CAAAA,MAAQA,IAAIL,IAAI,KAAK,kBAChD;gBACA,MAAM,CAACQ,MAAMC,QAAQC,QAAQ,GAAGiB,KAAK/C,IAAI,CAACkB,SAAS;gBAEnD,IAAIT,+BAASwC,MAAM/C,IAAI,GAAG;oBACxB,+BAAA;oBACA,MAAM2C,WAAWE,KAAKG,KAAK,CAACC,WAAW,CACpC,GAAEvB,KAAKwB,KAAM,CAAA,CAAA,EAAGvB,OAAOuB,KAAM,CAAA,CAAA,EAAGtB,QAAQsB,KAAM,EACjD;oBAEAH,MAAM9C,WAAW,KAAK,EAAE;oBACxB8C,MAAM9C,WAAW,CAACkD,IAAI,IACjBT,kBAAkBC,UAAUjB,MAAMC,QAAQC;oBAG/C,+DAAA;oBACAiB,KAAKO,WAAW,CACdxC,EAAEmB,gBAAgB,CAACnB,EAAEoB,UAAU,CAACW,WAAW/B,EAAEoB,UAAU,CAAC;gBAE5D;YACF;QAAA;IAEJ;IAEA,OAAO;QACLZ,MAAM;QACNiC,SAAS;YACPtC,gBAAgB;gBACduC,OAAMT,IAAI,EAAEE,KAAK;oBACf,8CAAA;oBACAH,cAAcC,MAAME;oBAEpB,MAAMjD,OAAO+C,KAAK/C,IAAI;oBACtB,IAAIe,2BAA2Bf,OAAO;wBACpC,MAAM,CAAC4B,MAAMC,QAAQC,QAAQ,GAAG9B,KAAKkB,SAAS;wBAC9C,IAAI,CAACR,6BAAOuC,MAAM/C,IAAI,GACpB,6HAAA;wBACA6C,KAAKO,WAAW,CAAC3B,kBAAkBC,MAAMC,QAAQC;oBAErD;gBACF;YACF;YACA2B,qBAAqB;gBACnBD,OAAMT,IAAI,EAAEE,KAAK;oBACf,IAAIvC,6BAAOuC,MAAM/C,IAAI,GACnB;wBAAA,IACE6C,KAAK/C,IAAI,CAAC0D,YAAY,CAACnC,MAAM,KAAK,KAClCwB,KAAK/C,IAAI,CAAC0D,YAAY,CAAC,EAAE,CAACtC,IAAI,KAAK,wBACnC2B,KAAK/C,IAAI,CAAC0D,YAAY,CAAC,EAAE,CAACC,EAAE,CAACvC,IAAI,KAAK,cACtC;4BACA,MAAMwC,WAAWb,KAAK/C,IAAI,CAAC0D,YAAY,CAAC,EAAE,CAACC,EAAE;4BAC7C,MAAME,OAAOd,KAAK/C,IAAI,CAAC0D,YAAY,CAAC,EAAE,CAACI,IAAI;4BAE3C,qEAAA;4BACAb,MAAM3C,kBAAkB,EAAEyD,IAAIH;4BAE9B,IAAIC,QAAQ9C,2BAA2B8C,OAAO;gCAC5C,MAAM,CAACjC,MAAMC,QAAQC,QAAQ,GAAG+B,KAAK3C,SAAS;gCAE9C,uIAAA;gCACA6B,KAAKiB,mBAAmB,CACtB5B,gBAAgBwB,UAAUhC,MAAMC,QAAQC;gCAG1C,iFAAA;gCACAmB,MAAM7C,4BAA4B,EAAE2D,IAAIH,SAAStC,IAAI;4BACvD;wBACF;oBAAA;gBAEJ;YACF;YACAd,YAAY;gBACVyD,MAAKlB,IAAI,EAAEE,KAAK;oBACd,MAAMf,aAAae,MAAM7C,4BAA4B,EAAE8D,IACrDnB,KAAK/C,IAAI,CAACsB,IACZ;oBACA,IAAIY,cAAc,CAACe,MAAM3C,kBAAkB,EAAE4D,IAAInB,KAAK/C,IAAI,GAAG;wBAC3D,wCAAA;wBACA,MAAMmE,eAAerD,EAAEoB,UAAU,CAACa,KAAK/C,IAAI,CAACsB,IAAI;wBAChDyB,KAAKO,WAAW,CACdxC,EAAEmB,gBAAgB,CAACkC,cAAcrD,EAAEoB,UAAU,CAAC;wBAEhDe,MAAM3C,kBAAkB,EAAEyD,IAAII;oBAChC;gBACF;YACF;YACAC,SAAS;gBACPZ,OAAMa,CAAC,EAAEpB,KAAK;oBACZA,MAAM7C,4BAA4B,GAAG,IAAIC;oBACzC4C,MAAM3C,kBAAkB,GAAG,IAAID;gBACjC;gBACA4D,MAAKlB,IAAI,EAAEE,KAAK;oBACd,IAAIA,MAAM9C,WAAW,EACnB,2DAAA;oBACA4C,KAAKuB,gBAAgB,CAAC,QAAQrB,MAAM9C,WAAW;gBAEnD;YACF;QACF;IACF;AACF","sources":["packages/utils/babel-plugin-transform-contextual-imports/src/index.ts"],"sourcesContent":["import type {PluginObj, NodePath, types as BabelTypes} from '@babel/core';\nimport {declare} from '@babel/helper-plugin-utils';\n\ninterface Opts {\n /** @deprecated Use \"node\" instead */\n server?: boolean;\n /** Use node safe import cond syntax */\n node?: boolean;\n}\n\ninterface State {\n /** Plugin options */\n opts: Opts;\n /** @deprecated Statement types didn't work so using any */\n importNodes?: any[];\n /** Set of identifier names that need to be mutated after import was transformed */\n conditionalImportIdentifiers?: Set<string>;\n /** Set of identifiers that have been visited in the exit pass, to avoid adding the load property multiple times */\n visitedIdentifiers?: Set<BabelTypes.Identifier>;\n}\n\nconst isServer = (opts: Opts) => {\n return 'server' in opts && opts.server;\n};\n\nconst isNode = (opts: Opts): boolean => !!('node' in opts && opts.node);\n\nexport default declare((api): PluginObj<State> => {\n const {types: t} = api;\n\n const isImportCondCallExpression = (\n node: BabelTypes.Node,\n ): node is BabelTypes.CallExpression & {\n arguments: [\n BabelTypes.StringLiteral,\n BabelTypes.StringLiteral,\n BabelTypes.StringLiteral,\n ];\n } => {\n if (\n node.type === 'CallExpression' &&\n node.callee.type === 'Identifier' &&\n node.callee.name === 'importCond'\n ) {\n if (\n node.arguments.length === 3 &&\n node.arguments.every(\n (arg): arg is BabelTypes.StringLiteral =>\n arg.type === 'StringLiteral',\n )\n ) {\n return true;\n } else {\n // Simple error for incorrect syntax (since it's documented with the type)\n throw new Error('importCond must have three string literal arguments');\n }\n }\n\n return false;\n };\n\n const buildCondFunction = (\n cond: BabelTypes.StringLiteral,\n ifTrue: BabelTypes.StringLiteral,\n ifFalse: BabelTypes.StringLiteral,\n ) =>\n t.conditionalExpression(\n t.logicalExpression(\n '&&',\n t.memberExpression(t.identifier('globalThis'), t.identifier('__MCOND')),\n t.callExpression(\n t.memberExpression(\n t.identifier('globalThis'),\n t.identifier('__MCOND'),\n ),\n [cond],\n ),\n ),\n t.memberExpression(\n t.callExpression(t.identifier('require'), [ifTrue]),\n t.identifier('default'),\n ),\n t.memberExpression(\n t.callExpression(t.identifier('require'), [ifFalse]),\n t.identifier('default'),\n ),\n );\n\n const buildNodeObject = (\n identifier: BabelTypes.Identifier,\n cond: BabelTypes.StringLiteral,\n ifTrue: BabelTypes.StringLiteral,\n ifFalse: BabelTypes.StringLiteral,\n ) => [\n // Create object containing imports\n t.variableDeclaration('const', [\n t.variableDeclarator(\n identifier,\n t.objectExpression([\n t.objectProperty(\n t.identifier('ifTrue'),\n t.memberExpression(\n t.callExpression(t.identifier('require'), [ifTrue]),\n t.identifier('default'),\n ),\n ),\n t.objectProperty(\n t.identifier('ifFalse'),\n t.memberExpression(\n t.callExpression(t.identifier('require'), [ifFalse]),\n t.identifier('default'),\n ),\n ),\n ]),\n ),\n ]),\n\n // Create lazy getter via the load property on the object.\n // This is node module resolution safe because each time the import is accessed, we re-evaluate the condition.\n t.expressionStatement(\n t.callExpression(\n t.memberExpression(\n t.identifier('Object'),\n t.identifier('defineProperty'),\n ),\n [\n identifier,\n t.stringLiteral('load'),\n t.objectExpression([\n t.objectProperty(\n t.identifier('get'),\n t.arrowFunctionExpression(\n [],\n t.conditionalExpression(\n t.logicalExpression(\n '&&',\n t.memberExpression(\n t.identifier('globalThis'),\n t.identifier('__MCOND'),\n ),\n t.callExpression(\n t.memberExpression(\n t.identifier('globalThis'),\n t.identifier('__MCOND'),\n ),\n [cond],\n ),\n ),\n t.memberExpression(identifier, t.identifier('ifTrue')),\n t.memberExpression(identifier, t.identifier('ifFalse')),\n ),\n ),\n ),\n ]),\n ],\n ),\n ),\n ];\n\n const buildServerObject = (\n identUid: string,\n cond: BabelTypes.StringLiteral,\n ifTrue: BabelTypes.StringLiteral,\n ifFalse: BabelTypes.StringLiteral,\n ) => [\n // Create object containing imports\n t.variableDeclaration('const', [\n t.variableDeclarator(\n t.identifier(identUid),\n t.objectExpression([\n t.objectProperty(\n t.identifier('ifTrue'),\n t.memberExpression(\n t.callExpression(t.identifier('require'), [ifTrue]),\n t.identifier('default'),\n ),\n ),\n t.objectProperty(\n t.identifier('ifFalse'),\n t.memberExpression(\n t.callExpression(t.identifier('require'), [ifFalse]),\n t.identifier('default'),\n ),\n ),\n ]),\n ),\n ]),\n\n // Create lazy getter via the load property on the object\n t.expressionStatement(\n t.callExpression(\n t.memberExpression(\n t.identifier('Object'),\n t.identifier('defineProperty'),\n ),\n [\n t.identifier(identUid),\n t.stringLiteral('load'),\n t.objectExpression([\n t.objectProperty(\n t.identifier('get'),\n t.arrowFunctionExpression(\n [],\n t.conditionalExpression(\n t.logicalExpression(\n '&&',\n t.memberExpression(\n t.identifier('globalThis'),\n t.identifier('__MCOND'),\n ),\n t.callExpression(\n t.memberExpression(\n t.identifier('globalThis'),\n t.identifier('__MCOND'),\n ),\n [cond],\n ),\n ),\n t.memberExpression(\n t.identifier(identUid),\n t.identifier('ifTrue'),\n ),\n t.memberExpression(\n t.identifier(identUid),\n t.identifier('ifFalse'),\n ),\n ),\n ),\n ),\n ]),\n ],\n ),\n ),\n ];\n\n const checkIsServer = (\n path: NodePath<BabelTypes.CallExpression>,\n state: State,\n ) => {\n if (\n path.node.callee.type === 'Identifier' &&\n path.node.callee.name === 'importCond'\n ) {\n if (\n path.node.arguments.length == 3 &&\n path.node.arguments.every((arg) => arg.type === 'StringLiteral')\n ) {\n const [cond, ifTrue, ifFalse] = path.node.arguments;\n\n if (isServer(state.opts)) {\n // Make module pass lazy in ssr\n const identUid = path.scope.generateUid(\n `${cond.value}$${ifTrue.value}$${ifFalse.value}`,\n );\n\n state.importNodes ??= [];\n state.importNodes.push(\n ...buildServerObject(identUid, cond, ifTrue, ifFalse),\n );\n\n // Replace call expression with reference to lazy object getter\n path.replaceWith(\n t.memberExpression(t.identifier(identUid), t.identifier('load')),\n );\n }\n }\n }\n };\n\n return {\n name: '@atlaspack/babel-plugin-transform-contextual-imports',\n visitor: {\n CallExpression: {\n enter(path, state) {\n // Preserve server behaviour in deletable code\n checkIsServer(path, state);\n\n const node = path.node;\n if (isImportCondCallExpression(node)) {\n const [cond, ifTrue, ifFalse] = node.arguments;\n if (!isNode(state.opts)) {\n // Replace the importCond call with a conditional require import, as a fallback for environments that don't support Atlaspack\n path.replaceWith(buildCondFunction(cond, ifTrue, ifFalse));\n }\n }\n },\n },\n VariableDeclaration: {\n enter(path, state) {\n if (isNode(state.opts)) {\n if (\n path.node.declarations.length === 1 &&\n path.node.declarations[0].type === 'VariableDeclarator' &&\n path.node.declarations[0].id.type === 'Identifier'\n ) {\n const importId = path.node.declarations[0].id;\n const call = path.node.declarations[0].init;\n\n // Mark identifier for object so we don't add the load property to it\n state.visitedIdentifiers?.add(importId);\n\n if (call && isImportCondCallExpression(call)) {\n const [cond, ifTrue, ifFalse] = call.arguments;\n\n // Replace with object containing imports and lazy getter, which allows us to load the correct import based on the condition at runtime\n path.replaceWithMultiple(\n buildNodeObject(importId, cond, ifTrue, ifFalse),\n );\n\n // Add identifier name to set so we can mutate all import usages in the exit pass\n state.conditionalImportIdentifiers?.add(importId.name);\n }\n }\n }\n },\n },\n Identifier: {\n exit(path, state) {\n const identifier = state.conditionalImportIdentifiers?.has(\n path.node.name,\n );\n if (identifier && !state.visitedIdentifiers?.has(path.node)) {\n // Add load property to the import usage\n const newIdentifer = t.identifier(path.node.name);\n path.replaceWith(\n t.memberExpression(newIdentifer, t.identifier('load')),\n );\n state.visitedIdentifiers?.add(newIdentifer);\n }\n },\n },\n Program: {\n enter(_, state) {\n state.conditionalImportIdentifiers = new Set();\n state.visitedIdentifiers = new Set();\n },\n exit(path, state) {\n if (state.importNodes) {\n // If there's an import node, add it to the top of the body\n path.unshiftContainer('body', state.importNodes);\n }\n },\n },\n },\n };\n});\n"],"names":["declare","Opts","server","node","State","opts","importNodes","conditionalImportIdentifiers","Set","visitedIdentifiers","BabelTypes","Identifier","isServer","isNode","api","PluginObj","types","t","isImportCondCallExpression","Node","CallExpression","arguments","StringLiteral","type","callee","name","length","every","arg","Error","buildCondFunction","cond","ifTrue","ifFalse","conditionalExpression","logicalExpression","memberExpression","identifier","callExpression","buildNodeObject","variableDeclaration","variableDeclarator","objectExpression","objectProperty","expressionStatement","stringLiteral","arrowFunctionExpression","buildServerObject","identUid","checkIsServer","path","NodePath","state","scope","generateUid","value","push","replaceWith","visitor","enter","VariableDeclaration","declarations","id","importId","call","init","add","replaceWithMultiple","exit","has","newIdentifer","Program","_","unshiftContainer"],"version":3,"file":"index.js.map","sourceRoot":"../../../../"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaspack/babel-plugin-transform-contextual-imports",
3
- "version": "2.13.2-canary.3683+cd964eed5",
3
+ "version": "2.13.2-canary.3684+0e563b5d3",
4
4
  "license": "(MIT OR Apache-2.0)",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -22,5 +22,5 @@
22
22
  "@types/babel__core": "^7.12.2",
23
23
  "@types/babel__helper-plugin-utils": "^7.10.3"
24
24
  },
25
- "gitHead": "cd964eed5a330ae63733656ded691d1ea3afe4e3"
25
+ "gitHead": "0e563b5d368de64ebef2ce7ce886353f804b60ab"
26
26
  }
package/src/index.ts CHANGED
@@ -2,18 +2,27 @@ import type {PluginObj, NodePath, types as BabelTypes} from '@babel/core';
2
2
  import {declare} from '@babel/helper-plugin-utils';
3
3
 
4
4
  interface Opts {
5
- // Use node safe import cond syntax
5
+ /** @deprecated Use "node" instead */
6
+ server?: boolean;
7
+ /** Use node safe import cond syntax */
6
8
  node?: boolean;
7
9
  }
8
10
 
9
11
  interface State {
12
+ /** Plugin options */
10
13
  opts: Opts;
11
- // Set of identifier names that need to be mutated after import was transformed
14
+ /** @deprecated Statement types didn't work so using any */
15
+ importNodes?: any[];
16
+ /** Set of identifier names that need to be mutated after import was transformed */
12
17
  conditionalImportIdentifiers?: Set<string>;
13
- // Set of identifiers that have been visited in the exit pass, to avoid adding the load property multiple times
18
+ /** Set of identifiers that have been visited in the exit pass, to avoid adding the load property multiple times */
14
19
  visitedIdentifiers?: Set<BabelTypes.Identifier>;
15
20
  }
16
21
 
22
+ const isServer = (opts: Opts) => {
23
+ return 'server' in opts && opts.server;
24
+ };
25
+
17
26
  const isNode = (opts: Opts): boolean => !!('node' in opts && opts.node);
18
27
 
19
28
  export default declare((api): PluginObj<State> => {
@@ -148,11 +157,124 @@ export default declare((api): PluginObj<State> => {
148
157
  ),
149
158
  ];
150
159
 
160
+ const buildServerObject = (
161
+ identUid: string,
162
+ cond: BabelTypes.StringLiteral,
163
+ ifTrue: BabelTypes.StringLiteral,
164
+ ifFalse: BabelTypes.StringLiteral,
165
+ ) => [
166
+ // Create object containing imports
167
+ t.variableDeclaration('const', [
168
+ t.variableDeclarator(
169
+ t.identifier(identUid),
170
+ t.objectExpression([
171
+ t.objectProperty(
172
+ t.identifier('ifTrue'),
173
+ t.memberExpression(
174
+ t.callExpression(t.identifier('require'), [ifTrue]),
175
+ t.identifier('default'),
176
+ ),
177
+ ),
178
+ t.objectProperty(
179
+ t.identifier('ifFalse'),
180
+ t.memberExpression(
181
+ t.callExpression(t.identifier('require'), [ifFalse]),
182
+ t.identifier('default'),
183
+ ),
184
+ ),
185
+ ]),
186
+ ),
187
+ ]),
188
+
189
+ // Create lazy getter via the load property on the object
190
+ t.expressionStatement(
191
+ t.callExpression(
192
+ t.memberExpression(
193
+ t.identifier('Object'),
194
+ t.identifier('defineProperty'),
195
+ ),
196
+ [
197
+ t.identifier(identUid),
198
+ t.stringLiteral('load'),
199
+ t.objectExpression([
200
+ t.objectProperty(
201
+ t.identifier('get'),
202
+ t.arrowFunctionExpression(
203
+ [],
204
+ t.conditionalExpression(
205
+ t.logicalExpression(
206
+ '&&',
207
+ t.memberExpression(
208
+ t.identifier('globalThis'),
209
+ t.identifier('__MCOND'),
210
+ ),
211
+ t.callExpression(
212
+ t.memberExpression(
213
+ t.identifier('globalThis'),
214
+ t.identifier('__MCOND'),
215
+ ),
216
+ [cond],
217
+ ),
218
+ ),
219
+ t.memberExpression(
220
+ t.identifier(identUid),
221
+ t.identifier('ifTrue'),
222
+ ),
223
+ t.memberExpression(
224
+ t.identifier(identUid),
225
+ t.identifier('ifFalse'),
226
+ ),
227
+ ),
228
+ ),
229
+ ),
230
+ ]),
231
+ ],
232
+ ),
233
+ ),
234
+ ];
235
+
236
+ const checkIsServer = (
237
+ path: NodePath<BabelTypes.CallExpression>,
238
+ state: State,
239
+ ) => {
240
+ if (
241
+ path.node.callee.type === 'Identifier' &&
242
+ path.node.callee.name === 'importCond'
243
+ ) {
244
+ if (
245
+ path.node.arguments.length == 3 &&
246
+ path.node.arguments.every((arg) => arg.type === 'StringLiteral')
247
+ ) {
248
+ const [cond, ifTrue, ifFalse] = path.node.arguments;
249
+
250
+ if (isServer(state.opts)) {
251
+ // Make module pass lazy in ssr
252
+ const identUid = path.scope.generateUid(
253
+ `${cond.value}$${ifTrue.value}$${ifFalse.value}`,
254
+ );
255
+
256
+ state.importNodes ??= [];
257
+ state.importNodes.push(
258
+ ...buildServerObject(identUid, cond, ifTrue, ifFalse),
259
+ );
260
+
261
+ // Replace call expression with reference to lazy object getter
262
+ path.replaceWith(
263
+ t.memberExpression(t.identifier(identUid), t.identifier('load')),
264
+ );
265
+ }
266
+ }
267
+ }
268
+ };
269
+
151
270
  return {
152
271
  name: '@atlaspack/babel-plugin-transform-contextual-imports',
153
272
  visitor: {
154
273
  CallExpression: {
155
274
  enter(path, state) {
275
+ // Preserve server behaviour in deletable code
276
+ checkIsServer(path, state);
277
+
156
278
  const node = path.node;
157
279
  if (isImportCondCallExpression(node)) {
158
280
  const [cond, ifTrue, ifFalse] = node.arguments;
@@ -212,6 +334,12 @@ export default declare((api): PluginObj<State> => {
212
334
  state.conditionalImportIdentifiers = new Set();
213
335
  state.visitedIdentifiers = new Set();
214
336
  },
337
+ exit(path, state) {
338
+ if (state.importNodes) {
339
+ // If there's an import node, add it to the top of the body
340
+ path.unshiftContainer('body', state.importNodes);
341
+ }
342
+ },
215
343
  },
216
344
  },
217
345
  };
@@ -22,7 +22,30 @@ describe('@atlaspack/babel-plugin-transform-contextual-imports', () => {
22
22
  );
23
23
  });
24
24
 
25
- it('should transform importCond to ssr safe code', () => {
25
+ it('should transform importCond to server (deprecated) lazy code', () => {
26
+ const input = `
27
+ importCond('CONDITION', 'IF_TRUE', 'IF_FALSE');
28
+ `;
29
+ let {code: transformed} = babel.transformSync(input, {
30
+ configFile: false,
31
+ presets: [],
32
+ plugins: [[plugin, {server: true}]],
33
+ });
34
+
35
+ assert(
36
+ transformed ===
37
+ `const _CONDITION$IF_TRUE$IF_FALSE = {
38
+ ifTrue: require('IF_TRUE').default,
39
+ ifFalse: require('IF_FALSE').default
40
+ };
41
+ Object.defineProperty(_CONDITION$IF_TRUE$IF_FALSE, "load", {
42
+ get: () => globalThis.__MCOND && globalThis.__MCOND('CONDITION') ? _CONDITION$IF_TRUE$IF_FALSE.ifTrue : _CONDITION$IF_TRUE$IF_FALSE.ifFalse
43
+ });
44
+ _CONDITION$IF_TRUE$IF_FALSE.load;`,
45
+ );
46
+ });
47
+
48
+ it('should transform importCond to node lazy code', () => {
26
49
  const input = `
27
50
  const Imported = importCond('CONDITION', 'IF_TRUE', 'IF_FALSE');
28
51