@intlayer/babel 9.3.0 → 9.3.2
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/README.md +24 -24
- package/dist/cjs/_virtual/_rolldown/runtime.cjs +1 -2
- package/dist/cjs/babel-plugin-intlayer-extract.cjs.map +1 -1
- package/dist/cjs/babel-plugin-intlayer-field-rename.cjs +66 -8
- package/dist/cjs/babel-plugin-intlayer-field-rename.cjs.map +1 -1
- package/dist/cjs/babel-plugin-intlayer-optimize.cjs +9 -5
- package/dist/cjs/babel-plugin-intlayer-optimize.cjs.map +1 -1
- package/dist/cjs/babel-plugin-intlayer-purge.cjs.map +1 -1
- package/dist/cjs/babel-plugin-intlayer-usage-analyzer.cjs +142 -54
- package/dist/cjs/babel-plugin-intlayer-usage-analyzer.cjs.map +1 -1
- package/dist/cjs/babelParser.cjs.map +1 -1
- package/dist/cjs/extractContent/babelProcessor.cjs +57 -57
- package/dist/cjs/extractContent/babelProcessor.cjs.map +1 -1
- package/dist/cjs/extractContent/contentWriter.cjs +3 -2
- package/dist/cjs/extractContent/contentWriter.cjs.map +1 -1
- package/dist/cjs/extractContent/extractContent.cjs +7 -6
- package/dist/cjs/extractContent/extractContent.cjs.map +1 -1
- package/dist/cjs/extractContent/index.cjs +0 -1
- package/dist/cjs/extractContent/processTsxFile.cjs.map +1 -1
- package/dist/cjs/extractContent/utils/constants.cjs +0 -14
- package/dist/cjs/extractContent/utils/constants.cjs.map +1 -1
- package/dist/cjs/extractContent/utils/detectPackageName.cjs.map +1 -1
- package/dist/cjs/extractContent/utils/extractDictionaryInfo.cjs +5 -3
- package/dist/cjs/extractContent/utils/extractDictionaryInfo.cjs.map +1 -1
- package/dist/cjs/extractContent/utils/extractDictionaryKey.cjs.map +1 -1
- package/dist/cjs/extractContent/utils/generateKey.cjs +0 -1
- package/dist/cjs/extractContent/utils/generateKey.cjs.map +1 -1
- package/dist/cjs/extractContent/utils/getExistingIntlayerInfo.cjs.map +1 -1
- package/dist/cjs/extractContent/utils/index.cjs +1 -4
- package/dist/cjs/extractContent/utils/resolveDictionaryKey.cjs.map +1 -1
- package/dist/cjs/extractScriptBlocks.cjs.map +1 -1
- package/dist/cjs/getExtractPluginOptions.cjs +4 -2
- package/dist/cjs/getExtractPluginOptions.cjs.map +1 -1
- package/dist/cjs/getOptimizePluginOptions.cjs.map +1 -1
- package/dist/cjs/getPurgePluginOptions.cjs.map +1 -1
- package/dist/cjs/index.cjs +1 -1
- package/dist/cjs/transformers.cjs.map +1 -1
- package/dist/esm/babel-plugin-intlayer-field-rename.mjs +67 -9
- package/dist/esm/babel-plugin-intlayer-field-rename.mjs.map +1 -1
- package/dist/esm/babel-plugin-intlayer-optimize.mjs +9 -5
- package/dist/esm/babel-plugin-intlayer-optimize.mjs.map +1 -1
- package/dist/esm/babel-plugin-intlayer-usage-analyzer.mjs +142 -54
- package/dist/esm/babel-plugin-intlayer-usage-analyzer.mjs.map +1 -1
- package/dist/esm/extractContent/babelProcessor.mjs +51 -51
- package/dist/esm/extractContent/babelProcessor.mjs.map +1 -1
- package/dist/esm/extractContent/contentWriter.mjs +3 -2
- package/dist/esm/extractContent/contentWriter.mjs.map +1 -1
- package/dist/esm/extractContent/extractContent.mjs +5 -4
- package/dist/esm/extractContent/extractContent.mjs.map +1 -1
- package/dist/esm/extractContent/index.mjs +2 -2
- package/dist/esm/extractContent/utils/constants.mjs +1 -13
- package/dist/esm/extractContent/utils/constants.mjs.map +1 -1
- package/dist/esm/extractContent/utils/extractDictionaryInfo.mjs +5 -3
- package/dist/esm/extractContent/utils/extractDictionaryInfo.mjs.map +1 -1
- package/dist/esm/extractContent/utils/getExistingIntlayerInfo.mjs.map +1 -1
- package/dist/esm/extractContent/utils/index.mjs +2 -3
- package/dist/esm/getExtractPluginOptions.mjs +4 -2
- package/dist/esm/getExtractPluginOptions.mjs.map +1 -1
- package/dist/esm/index.mjs +3 -3
- package/dist/types/babel-plugin-intlayer-field-rename.d.ts.map +1 -1
- package/dist/types/babel-plugin-intlayer-usage-analyzer.d.ts +16 -1
- package/dist/types/babel-plugin-intlayer-usage-analyzer.d.ts.map +1 -1
- package/dist/types/extractContent/babelProcessor.d.ts.map +1 -1
- package/dist/types/extractContent/extractContent.d.ts.map +1 -1
- package/dist/types/extractContent/index.d.ts +2 -2
- package/dist/types/extractContent/utils/constants.d.ts +1 -7
- package/dist/types/extractContent/utils/constants.d.ts.map +1 -1
- package/dist/types/extractContent/utils/index.d.ts +2 -3
- package/dist/types/index.d.ts +3 -3
- package/package.json +9 -10
- package/dist/cjs/extractContent/utils/shouldExtract.cjs +0 -39
- package/dist/cjs/extractContent/utils/shouldExtract.cjs.map +0 -1
- package/dist/esm/extractContent/utils/shouldExtract.mjs +0 -37
- package/dist/esm/extractContent/utils/shouldExtract.mjs.map +0 -1
- package/dist/types/extractContent/utils/shouldExtract.d.ts +0 -15
- package/dist/types/extractContent/utils/shouldExtract.d.ts.map +0 -1
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
|
-
|
|
3
2
|
//#region src/babel-plugin-intlayer-usage-analyzer.ts
|
|
4
3
|
const createPruneContext = () => ({
|
|
5
4
|
dictionaryKeyToFieldUsageMap: /* @__PURE__ */ new Map(),
|
|
@@ -55,6 +54,21 @@ const preserveNestedDictionaryFields = (pruneContext, nestedDictionaryReferences
|
|
|
55
54
|
for (const nestedField of nestedFields) currentFieldUsage.add(nestedField);
|
|
56
55
|
}
|
|
57
56
|
};
|
|
57
|
+
/**
|
|
58
|
+
* Methods the runtime attaches to a resolved content object rather than fields
|
|
59
|
+
* declared in a `.content` file.
|
|
60
|
+
*
|
|
61
|
+
* `vanilla-intlayer`'s `useIntlayer` / `useDictionary` assign `onChange` onto
|
|
62
|
+
* the content they return, so `useIntlayer('app').onChange(cb)` is a
|
|
63
|
+
* subscription — not a read of a field named `onChange`. Without this list the
|
|
64
|
+
* analyser records `onChange` as the only consumed field and the purge pass
|
|
65
|
+
* strips every real field from the compiled dictionary.
|
|
66
|
+
*
|
|
67
|
+
* The analyser looks *through* these calls: the callback parameter is analysed
|
|
68
|
+
* as a fresh content root, and the call result is analysed again because the
|
|
69
|
+
* helpers return the content object for chaining.
|
|
70
|
+
*/
|
|
71
|
+
const CHAINABLE_RUNTIME_METHOD_NAMES = /* @__PURE__ */ new Set(["onChange"]);
|
|
58
72
|
/** Canonical intlayer caller names that trigger usage analysis. */
|
|
59
73
|
const INTLAYER_CALLER_NAMES = ["useIntlayer", "getIntlayer"];
|
|
60
74
|
/**
|
|
@@ -99,7 +113,6 @@ const recordFieldUsage = (pruneContext, dictionaryKey, fieldUsage) => {
|
|
|
99
113
|
* const result = useIntlayer('key') → records 'all' (untracked binding)
|
|
100
114
|
*/
|
|
101
115
|
const analyzeCallExpressionUsage = (babelTypes, pruneContext, callExpressionPath, dictionaryKey, currentSourceFilePath, isSfcFile) => {
|
|
102
|
-
const parentNode = callExpressionPath.parent;
|
|
103
116
|
/** Mark the dictionary key as having an untracked binding in this file. */
|
|
104
117
|
const markUntrackedBinding = () => {
|
|
105
118
|
const existingPaths = pruneContext.dictionaryKeysWithUntrackedBindings.get(dictionaryKey) ?? [];
|
|
@@ -227,32 +240,64 @@ const analyzeCallExpressionUsage = (babelTypes, pruneContext, callExpressionPath
|
|
|
227
240
|
}
|
|
228
241
|
return true;
|
|
229
242
|
};
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
if (
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
return;
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
243
|
+
/**
|
|
244
|
+
* Returns the call path when `memberExprPath` is a chainable runtime helper
|
|
245
|
+
* being invoked (`content.onChange(cb)`), otherwise `undefined`.
|
|
246
|
+
*
|
|
247
|
+
* See {@link CHAINABLE_RUNTIME_METHOD_NAMES}: a bare `content.onChange`
|
|
248
|
+
* reference that is never called is treated as an ordinary field access, so
|
|
249
|
+
* only the invoked form is looked through.
|
|
250
|
+
*/
|
|
251
|
+
const getChainedRuntimeCallPath = (memberExprPath, fieldName) => {
|
|
252
|
+
if (!CHAINABLE_RUNTIME_METHOD_NAMES.has(fieldName)) return void 0;
|
|
253
|
+
if (!memberExprPath) return void 0;
|
|
254
|
+
const callPath = memberExprPath.parentPath;
|
|
255
|
+
if (!callPath) return void 0;
|
|
256
|
+
if (!callPath.isCallExpression() && !callPath.isOptionalCallExpression()) return;
|
|
257
|
+
if (callPath.node.callee !== memberExprPath.node) return;
|
|
258
|
+
return callPath;
|
|
259
|
+
};
|
|
260
|
+
/**
|
|
261
|
+
* Analyses the callbacks handed to a chainable runtime helper.
|
|
262
|
+
*
|
|
263
|
+
* The callback receives the freshly-resolved content root, so its parameter
|
|
264
|
+
* is walked exactly like `const content = useIntlayer('key')` — either as a
|
|
265
|
+
* plain binding or as a destructuring pattern.
|
|
266
|
+
*/
|
|
267
|
+
const analyzeChainedCallbackArguments = (callPath) => {
|
|
268
|
+
const argumentPaths = callPath.get("arguments");
|
|
269
|
+
for (const argumentPath of argumentPaths) {
|
|
270
|
+
if (!argumentPath.isArrowFunctionExpression() && !argumentPath.isFunctionExpression()) continue;
|
|
271
|
+
const [firstParameterPath] = argumentPath.get("params");
|
|
272
|
+
if (!firstParameterPath) continue;
|
|
273
|
+
if (firstParameterPath.isIdentifier()) {
|
|
274
|
+
const parameterBinding = argumentPath.scope.getBinding(firstParameterPath.node.name);
|
|
275
|
+
if (!parameterBinding) {
|
|
276
|
+
markUntrackedBinding();
|
|
277
|
+
continue;
|
|
278
|
+
}
|
|
279
|
+
const accessedFieldNames = /* @__PURE__ */ new Set();
|
|
280
|
+
if (analyzeContentBindingReferences(parameterBinding, accessedFieldNames)) markUntrackedBinding();
|
|
281
|
+
else recordFieldUsage(pruneContext, dictionaryKey, accessedFieldNames);
|
|
282
|
+
continue;
|
|
283
|
+
}
|
|
284
|
+
if (firstParameterPath.isObjectPattern()) {
|
|
285
|
+
const accessedFieldNames = /* @__PURE__ */ new Set();
|
|
286
|
+
if (collectFieldsFromObjectPattern(firstParameterPath.node, argumentPath, accessedFieldNames)) recordFieldUsage(pruneContext, dictionaryKey, accessedFieldNames);
|
|
287
|
+
else recordFieldUsage(pruneContext, dictionaryKey, "all");
|
|
288
|
+
continue;
|
|
289
|
+
}
|
|
251
290
|
markUntrackedBinding();
|
|
252
|
-
return;
|
|
253
291
|
}
|
|
254
|
-
|
|
255
|
-
|
|
292
|
+
};
|
|
293
|
+
/**
|
|
294
|
+
* Walks every reference of a local binding holding the content root,
|
|
295
|
+
* collecting the top-level fields it reads into `accessedTopLevelFieldNames`.
|
|
296
|
+
*
|
|
297
|
+
* @returns `true` when a reference escaped static tracking, meaning the whole
|
|
298
|
+
* dictionary must be kept.
|
|
299
|
+
*/
|
|
300
|
+
const analyzeContentBindingReferences = (variableBinding, accessedTopLevelFieldNames) => {
|
|
256
301
|
for (const variableReferencePath of variableBinding.referencePaths) {
|
|
257
302
|
const referenceParentNode = variableReferencePath.parent;
|
|
258
303
|
if ((babelTypes.isMemberExpression(referenceParentNode) || babelTypes.isOptionalMemberExpression(referenceParentNode)) && referenceParentNode.object === variableReferencePath.node) {
|
|
@@ -261,17 +306,18 @@ const analyzeCallExpressionUsage = (babelTypes, pruneContext, callExpressionPath
|
|
|
261
306
|
if (!memberExpressionNode.computed && babelTypes.isIdentifier(memberExpressionNode.property)) fieldName = memberExpressionNode.property.name;
|
|
262
307
|
else if (memberExpressionNode.computed && babelTypes.isStringLiteral(memberExpressionNode.property)) fieldName = memberExpressionNode.property.value;
|
|
263
308
|
if (fieldName) {
|
|
264
|
-
accessedTopLevelFieldNames.add(fieldName);
|
|
265
309
|
const memberExprPath = variableReferencePath.parentPath;
|
|
310
|
+
const chainedCallPath = getChainedRuntimeCallPath(memberExprPath, fieldName);
|
|
311
|
+
if (chainedCallPath) {
|
|
312
|
+
analyzeChainedCallbackArguments(chainedCallPath);
|
|
313
|
+
analyzeContentRoot(chainedCallPath);
|
|
314
|
+
continue;
|
|
315
|
+
}
|
|
316
|
+
accessedTopLevelFieldNames.add(fieldName);
|
|
266
317
|
if (memberExprPath) analyzeOpaqueUsage(memberExprPath, [fieldName]);
|
|
267
|
-
} else
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
}
|
|
271
|
-
} else if (babelTypes.isArrayExpression(referenceParentNode)) {
|
|
272
|
-
hasUntrackedReferenceAccess = true;
|
|
273
|
-
break;
|
|
274
|
-
} else if ((babelTypes.isCallExpression(referenceParentNode) || babelTypes.isOptionalCallExpression(referenceParentNode)) && referenceParentNode.callee === variableReferencePath.node) {
|
|
318
|
+
} else return true;
|
|
319
|
+
} else if (babelTypes.isArrayExpression(referenceParentNode)) return true;
|
|
320
|
+
else if ((babelTypes.isCallExpression(referenceParentNode) || babelTypes.isOptionalCallExpression(referenceParentNode)) && referenceParentNode.callee === variableReferencePath.node) {
|
|
275
321
|
const callExprPath = variableReferencePath.parentPath;
|
|
276
322
|
const callParent = callExprPath?.parent;
|
|
277
323
|
if (callParent && (babelTypes.isMemberExpression(callParent) || babelTypes.isOptionalMemberExpression(callParent)) && callParent.object === callExprPath?.node) {
|
|
@@ -280,30 +326,71 @@ const analyzeCallExpressionUsage = (babelTypes, pruneContext, callExpressionPath
|
|
|
280
326
|
if (!memberExpr.computed && babelTypes.isIdentifier(memberExpr.property)) fieldName = memberExpr.property.name;
|
|
281
327
|
else if (memberExpr.computed && babelTypes.isStringLiteral(memberExpr.property)) fieldName = memberExpr.property.value;
|
|
282
328
|
if (fieldName) {
|
|
283
|
-
accessedTopLevelFieldNames.add(fieldName);
|
|
284
329
|
const memberExprPath = callExprPath?.parentPath;
|
|
330
|
+
const chainedCallPath = getChainedRuntimeCallPath(memberExprPath, fieldName);
|
|
331
|
+
if (chainedCallPath) {
|
|
332
|
+
analyzeChainedCallbackArguments(chainedCallPath);
|
|
333
|
+
analyzeContentRoot(chainedCallPath);
|
|
334
|
+
continue;
|
|
335
|
+
}
|
|
336
|
+
accessedTopLevelFieldNames.add(fieldName);
|
|
285
337
|
if (memberExprPath) analyzeOpaqueUsage(memberExprPath, [fieldName]);
|
|
286
|
-
} else
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
338
|
+
} else return true;
|
|
339
|
+
} else if (callParent && babelTypes.isVariableDeclarator(callParent) && babelTypes.isObjectPattern(callParent.id) && callExprPath && collectFieldsFromObjectPattern(callParent.id, callExprPath, accessedTopLevelFieldNames)) {} else return true;
|
|
340
|
+
} else return true;
|
|
341
|
+
}
|
|
342
|
+
return false;
|
|
343
|
+
};
|
|
344
|
+
/**
|
|
345
|
+
* Analyses how the content root referenced by `rootPath` is consumed.
|
|
346
|
+
*
|
|
347
|
+
* `rootPath` is the `useIntlayer('key')` call itself, or any expression that
|
|
348
|
+
* evaluates back to the same content object — currently the result of a
|
|
349
|
+
* chainable runtime helper such as `.onChange(…)`.
|
|
350
|
+
*/
|
|
351
|
+
const analyzeContentRoot = (rootPath) => {
|
|
352
|
+
const parentNode = rootPath.parent;
|
|
353
|
+
if (babelTypes.isVariableDeclarator(parentNode) && babelTypes.isObjectPattern(parentNode.id)) {
|
|
354
|
+
const accessedFieldNames = /* @__PURE__ */ new Set();
|
|
355
|
+
if (collectFieldsFromObjectPattern(parentNode.id, rootPath, accessedFieldNames)) recordFieldUsage(pruneContext, dictionaryKey, accessedFieldNames);
|
|
356
|
+
else recordFieldUsage(pruneContext, dictionaryKey, "all");
|
|
357
|
+
return;
|
|
358
|
+
}
|
|
359
|
+
if ((babelTypes.isMemberExpression(parentNode) || babelTypes.isOptionalMemberExpression(parentNode)) && parentNode.object === rootPath.node) {
|
|
360
|
+
let fieldName;
|
|
361
|
+
if (!parentNode.computed && babelTypes.isIdentifier(parentNode.property)) fieldName = parentNode.property.name;
|
|
362
|
+
else if (parentNode.computed && babelTypes.isStringLiteral(parentNode.property)) fieldName = parentNode.property.value;
|
|
363
|
+
if (fieldName) {
|
|
364
|
+
const memberExprPath = rootPath.parentPath;
|
|
365
|
+
const chainedCallPath = getChainedRuntimeCallPath(memberExprPath, fieldName);
|
|
366
|
+
if (chainedCallPath) {
|
|
367
|
+
analyzeChainedCallbackArguments(chainedCallPath);
|
|
368
|
+
analyzeContentRoot(chainedCallPath);
|
|
369
|
+
return;
|
|
293
370
|
}
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
371
|
+
recordFieldUsage(pruneContext, dictionaryKey, /* @__PURE__ */ new Set([fieldName]));
|
|
372
|
+
if (memberExprPath) analyzeOpaqueUsage(memberExprPath, [fieldName]);
|
|
373
|
+
} else markUntrackedBinding();
|
|
374
|
+
return;
|
|
375
|
+
}
|
|
376
|
+
if (babelTypes.isVariableDeclarator(parentNode) && babelTypes.isIdentifier(parentNode.id)) {
|
|
377
|
+
const variableName = parentNode.id.name;
|
|
378
|
+
const variableBinding = rootPath.scope.getBinding(variableName);
|
|
379
|
+
if (!variableBinding) {
|
|
380
|
+
markUntrackedBinding();
|
|
381
|
+
return;
|
|
297
382
|
}
|
|
383
|
+
const accessedTopLevelFieldNames = /* @__PURE__ */ new Set();
|
|
384
|
+
if (analyzeContentBindingReferences(variableBinding, accessedTopLevelFieldNames)) markUntrackedBinding();
|
|
385
|
+
else if (isSfcFile) deferFrameworkAnalysis(variableName);
|
|
386
|
+
else if (variableBinding.referencePaths.length === 0) markUntrackedBinding();
|
|
387
|
+
else recordFieldUsage(pruneContext, dictionaryKey, accessedTopLevelFieldNames);
|
|
388
|
+
return;
|
|
298
389
|
}
|
|
299
|
-
if (
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
return;
|
|
304
|
-
}
|
|
305
|
-
if (babelTypes.isExpressionStatement(parentNode)) return;
|
|
306
|
-
markUntrackedBinding();
|
|
390
|
+
if (babelTypes.isExpressionStatement(parentNode)) return;
|
|
391
|
+
markUntrackedBinding();
|
|
392
|
+
};
|
|
393
|
+
analyzeContentRoot(callExpressionPath);
|
|
307
394
|
};
|
|
308
395
|
/**
|
|
309
396
|
* Reads a fully-static string from an AST node. Returns `undefined` for
|
|
@@ -647,6 +734,7 @@ const makeUsageAnalyzerBabelPlugin = (pruneContext, options) => ({ types: babelT
|
|
|
647
734
|
};
|
|
648
735
|
|
|
649
736
|
//#endregion
|
|
737
|
+
exports.CHAINABLE_RUNTIME_METHOD_NAMES = CHAINABLE_RUNTIME_METHOD_NAMES;
|
|
650
738
|
exports.DEFAULT_COMPAT_CALLERS = DEFAULT_COMPAT_CALLERS;
|
|
651
739
|
exports.INTLAYER_CALLER_NAMES = INTLAYER_CALLER_NAMES;
|
|
652
740
|
exports.createPruneContext = createPruneContext;
|