telemetry-plugin.js 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", {
  3. value: true
  4. });
  5. var _webpack = require("next/dist/compiled/webpack/webpack");
  6. // Map of a feature module to the file it belongs in the next package.
  7. const FEATURE_MODULE_MAP = new Map([
  8. [
  9. "next/image",
  10. "/next/image.js"
  11. ],
  12. [
  13. "next/future/image",
  14. "/next/future/image.js"
  15. ],
  16. [
  17. "next/script",
  18. "/next/script.js"
  19. ],
  20. [
  21. "next/dynamic",
  22. "/next/dynamic.js"
  23. ],
  24. ]);
  25. // List of build features used in webpack configuration
  26. const BUILD_FEATURES = [
  27. "swcLoader",
  28. "swcMinify",
  29. "swcRelay",
  30. "swcStyledComponents",
  31. "swcReactRemoveProperties",
  32. "swcExperimentalDecorators",
  33. "swcRemoveConsole",
  34. "swcImportSource",
  35. "swcEmotion",
  36. "swc/target/x86_64-apple-darwin",
  37. "swc/target/x86_64-unknown-linux-gnu",
  38. "swc/target/x86_64-pc-windows-msvc",
  39. "swc/target/i686-pc-windows-msvc",
  40. "swc/target/aarch64-unknown-linux-gnu",
  41. "swc/target/armv7-unknown-linux-gnueabihf",
  42. "swc/target/aarch64-apple-darwin",
  43. "swc/target/aarch64-linux-android",
  44. "swc/target/arm-linux-androideabi",
  45. "swc/target/x86_64-unknown-freebsd",
  46. "swc/target/x86_64-unknown-linux-musl",
  47. "swc/target/aarch64-unknown-linux-musl",
  48. "swc/target/aarch64-pc-windows-msvc",
  49. ];
  50. const ELIMINATED_PACKAGES = new Set();
  51. /**
  52. * Determine if there is a feature of interest in the specified 'module'.
  53. */ function findFeatureInModule(module) {
  54. if (module.type !== "javascript/auto") {
  55. return;
  56. }
  57. for (const [feature, path] of FEATURE_MODULE_MAP){
  58. if (module.identifier().replace(/\\/g, "/").endsWith(path)) {
  59. return feature;
  60. }
  61. }
  62. }
  63. /**
  64. * Find unique origin modules in the specified 'connections', which possibly
  65. * contains more than one connection for a module due to different types of
  66. * dependency.
  67. */ function findUniqueOriginModulesInConnections(connections) {
  68. const originModules = new Set();
  69. for (const connection of connections){
  70. if (!originModules.has(connection.originModule)) {
  71. originModules.add(connection.originModule);
  72. }
  73. }
  74. return originModules;
  75. }
  76. class TelemetryPlugin {
  77. usageTracker = new Map();
  78. // Build feature usage is on/off and is known before the build starts
  79. constructor(buildFeaturesMap){
  80. for (const featureName of BUILD_FEATURES){
  81. this.usageTracker.set(featureName, {
  82. featureName,
  83. invocationCount: buildFeaturesMap.get(featureName) ? 1 : 0
  84. });
  85. }
  86. for (const featureName1 of FEATURE_MODULE_MAP.keys()){
  87. this.usageTracker.set(featureName1, {
  88. featureName: featureName1,
  89. invocationCount: 0
  90. });
  91. }
  92. }
  93. apply(compiler) {
  94. compiler.hooks.make.tapAsync(TelemetryPlugin.name, async (compilation, callback)=>{
  95. compilation.hooks.finishModules.tapAsync(TelemetryPlugin.name, async (modules, modulesFinish)=>{
  96. for (const module of modules){
  97. const feature = findFeatureInModule(module);
  98. if (!feature) {
  99. continue;
  100. }
  101. const connections = compilation.moduleGraph.getIncomingConnections(module);
  102. const originModules = findUniqueOriginModulesInConnections(connections);
  103. this.usageTracker.get(feature).invocationCount = originModules.size;
  104. }
  105. modulesFinish();
  106. });
  107. callback();
  108. });
  109. if (compiler.options.mode === "production" && !compiler.watchMode) {
  110. compiler.hooks.compilation.tap(TelemetryPlugin.name, (compilation)=>{
  111. const moduleHooks = _webpack.NormalModule.getCompilationHooks(compilation);
  112. moduleHooks.loader.tap(TelemetryPlugin.name, (loaderContext)=>{
  113. loaderContext.eliminatedPackages = ELIMINATED_PACKAGES;
  114. });
  115. });
  116. }
  117. }
  118. usages() {
  119. return [
  120. ...this.usageTracker.values()
  121. ];
  122. }
  123. packagesUsedInServerSideProps() {
  124. return Array.from(ELIMINATED_PACKAGES);
  125. }
  126. }
  127. exports.TelemetryPlugin = TelemetryPlugin;
  128. //# sourceMappingURL=telemetry-plugin.js.map