get-config.js 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", {
  3. value: true
  4. });
  5. exports.default = getConfig;
  6. var _fs = require("fs");
  7. var _json5 = _interopRequireDefault(require("next/dist/compiled/json5"));
  8. var _core = require("next/dist/compiled/babel/core");
  9. var _coreLibConfig = _interopRequireDefault(require("next/dist/compiled/babel/core-lib-config"));
  10. var _util = require("./util");
  11. var Log = _interopRequireWildcard(require("../../output/log"));
  12. function getConfig({ source , target , loaderOptions , filename , inputSourceMap }) {
  13. const cacheCharacteristics = getCacheCharacteristics(loaderOptions, source, filename);
  14. if (loaderOptions.configFile) {
  15. // Ensures webpack invalidates the cache for this loader when the config file changes
  16. this.addDependency(loaderOptions.configFile);
  17. }
  18. const cacheKey = getCacheKey(cacheCharacteristics);
  19. if (configCache.has(cacheKey)) {
  20. const cachedConfig = configCache.get(cacheKey);
  21. return {
  22. ...cachedConfig,
  23. options: {
  24. ...cachedConfig.options,
  25. cwd: loaderOptions.cwd,
  26. root: loaderOptions.cwd,
  27. filename,
  28. sourceFileName: filename
  29. }
  30. };
  31. }
  32. if (loaderOptions.configFile && !configFiles.has(loaderOptions.configFile)) {
  33. configFiles.add(loaderOptions.configFile);
  34. Log.info(`Using external babel configuration from ${loaderOptions.configFile}`);
  35. }
  36. const freshConfig = getFreshConfig.call(this, cacheCharacteristics, loaderOptions, target, filename, inputSourceMap);
  37. configCache.set(cacheKey, freshConfig);
  38. return freshConfig;
  39. }
  40. function _interopRequireDefault(obj) {
  41. return obj && obj.__esModule ? obj : {
  42. default: obj
  43. };
  44. }
  45. function _getRequireWildcardCache() {
  46. if (typeof WeakMap !== "function") return null;
  47. var cache = new WeakMap();
  48. _getRequireWildcardCache = function() {
  49. return cache;
  50. };
  51. return cache;
  52. }
  53. function _interopRequireWildcard(obj) {
  54. if (obj && obj.__esModule) {
  55. return obj;
  56. }
  57. if (obj === null || typeof obj !== "object" && typeof obj !== "function") {
  58. return {
  59. default: obj
  60. };
  61. }
  62. var cache = _getRequireWildcardCache();
  63. if (cache && cache.has(obj)) {
  64. return cache.get(obj);
  65. }
  66. var newObj = {};
  67. var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;
  68. for(var key in obj){
  69. if (Object.prototype.hasOwnProperty.call(obj, key)) {
  70. var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null;
  71. if (desc && (desc.get || desc.set)) {
  72. Object.defineProperty(newObj, key, desc);
  73. } else {
  74. newObj[key] = obj[key];
  75. }
  76. }
  77. }
  78. newObj.default = obj;
  79. if (cache) {
  80. cache.set(obj, newObj);
  81. }
  82. return newObj;
  83. }
  84. const nextDistPath = /(next[\\/]dist[\\/]shared[\\/]lib)|(next[\\/]dist[\\/]client)|(next[\\/]dist[\\/]pages)/;
  85. const fileExtensionRegex = /\.([a-z]+)$/;
  86. function getCacheCharacteristics(loaderOptions, source, filename) {
  87. var ref;
  88. const { isServer , pagesDir } = loaderOptions;
  89. const isPageFile = filename.startsWith(pagesDir);
  90. const isNextDist = nextDistPath.test(filename);
  91. const hasModuleExports = source.indexOf("module.exports") !== -1;
  92. const fileExt = ((ref = fileExtensionRegex.exec(filename)) == null ? void 0 : ref[1]) || "unknown";
  93. return {
  94. isServer,
  95. isPageFile,
  96. isNextDist,
  97. hasModuleExports,
  98. fileExt
  99. };
  100. }
  101. /**
  102. * Return an array of Babel plugins, conditioned upon loader options and
  103. * source file characteristics.
  104. */ function getPlugins(loaderOptions, cacheCharacteristics) {
  105. const { isServer , isPageFile , isNextDist , hasModuleExports } = cacheCharacteristics;
  106. const { hasReactRefresh , development } = loaderOptions;
  107. const applyCommonJsItem = hasModuleExports ? (0, _core).createConfigItem(require("../plugins/commonjs"), {
  108. type: "plugin"
  109. }) : null;
  110. const reactRefreshItem = hasReactRefresh ? (0, _core).createConfigItem([
  111. require("next/dist/compiled/react-refresh/babel"),
  112. {
  113. skipEnvCheck: true
  114. },
  115. ], {
  116. type: "plugin"
  117. }) : null;
  118. const pageConfigItem = !isServer && isPageFile ? (0, _core).createConfigItem([
  119. require("../plugins/next-page-config")
  120. ], {
  121. type: "plugin"
  122. }) : null;
  123. const disallowExportAllItem = !isServer && isPageFile ? (0, _core).createConfigItem([
  124. require("../plugins/next-page-disallow-re-export-all-exports")
  125. ], {
  126. type: "plugin"
  127. }) : null;
  128. const transformDefineItem = (0, _core).createConfigItem([
  129. require.resolve("next/dist/compiled/babel/plugin-transform-define"),
  130. {
  131. "process.env.NODE_ENV": development ? "development" : "production",
  132. "typeof window": isServer ? "undefined" : "object",
  133. "process.browser": isServer ? false : true
  134. },
  135. "next-js-transform-define-instance",
  136. ], {
  137. type: "plugin"
  138. });
  139. const nextSsgItem = !isServer && isPageFile ? (0, _core).createConfigItem([
  140. require.resolve("../plugins/next-ssg-transform")
  141. ], {
  142. type: "plugin"
  143. }) : null;
  144. const commonJsItem = isNextDist ? (0, _core).createConfigItem(require("next/dist/compiled/babel/plugin-transform-modules-commonjs"), {
  145. type: "plugin"
  146. }) : null;
  147. return [
  148. reactRefreshItem,
  149. pageConfigItem,
  150. disallowExportAllItem,
  151. applyCommonJsItem,
  152. transformDefineItem,
  153. nextSsgItem,
  154. commonJsItem,
  155. ].filter(Boolean);
  156. }
  157. const isJsonFile = /\.(json|babelrc)$/;
  158. const isJsFile = /\.js$/;
  159. /**
  160. * While this function does block execution while reading from disk, it
  161. * should not introduce any issues. The function is only invoked when
  162. * generating a fresh config, and only a small handful of configs should
  163. * be generated during compilation.
  164. */ function getCustomBabelConfig(configFilePath) {
  165. if (isJsonFile.exec(configFilePath)) {
  166. const babelConfigRaw = (0, _fs).readFileSync(configFilePath, "utf8");
  167. return _json5.default.parse(babelConfigRaw);
  168. } else if (isJsFile.exec(configFilePath)) {
  169. return require(configFilePath);
  170. }
  171. throw new Error("The Next.js Babel loader does not support .mjs or .cjs config files.");
  172. }
  173. /**
  174. * Generate a new, flat Babel config, ready to be handed to Babel-traverse.
  175. * This config should have no unresolved overrides, presets, etc.
  176. */ function getFreshConfig(cacheCharacteristics, loaderOptions, target, filename, inputSourceMap) {
  177. let { isServer , pagesDir , development , hasJsxRuntime , configFile } = loaderOptions;
  178. let customConfig = configFile ? getCustomBabelConfig(configFile) : undefined;
  179. let options = {
  180. babelrc: false,
  181. cloneInputAst: false,
  182. filename,
  183. inputSourceMap: inputSourceMap || undefined,
  184. // Set the default sourcemap behavior based on Webpack's mapping flag,
  185. // but allow users to override if they want.
  186. sourceMaps: loaderOptions.sourceMaps === undefined ? this.sourceMap : loaderOptions.sourceMaps,
  187. // Ensure that Webpack will get a full absolute path in the sourcemap
  188. // so that it can properly map the module back to its internal cached
  189. // modules.
  190. sourceFileName: filename,
  191. plugins: [
  192. ...getPlugins(loaderOptions, cacheCharacteristics),
  193. ...(customConfig == null ? void 0 : customConfig.plugins) || [],
  194. ],
  195. // target can be provided in babelrc
  196. target: isServer ? undefined : customConfig == null ? void 0 : customConfig.target,
  197. // env can be provided in babelrc
  198. env: customConfig == null ? void 0 : customConfig.env,
  199. presets: (()=>{
  200. // If presets is defined the user will have next/babel in their babelrc
  201. if (customConfig == null ? void 0 : customConfig.presets) {
  202. return customConfig.presets;
  203. }
  204. // If presets is not defined the user will likely have "env" in their babelrc
  205. if (customConfig) {
  206. return undefined;
  207. }
  208. // If no custom config is provided the default is to use next/babel
  209. return [
  210. "next/babel"
  211. ];
  212. })(),
  213. overrides: loaderOptions.overrides,
  214. caller: {
  215. name: "next-babel-turbo-loader",
  216. supportsStaticESM: true,
  217. supportsDynamicImport: true,
  218. // Provide plugins with insight into webpack target.
  219. // https://github.com/babel/babel-loader/issues/787
  220. target: target,
  221. // Webpack 5 supports TLA behind a flag. We enable it by default
  222. // for Babel, and then webpack will throw an error if the experimental
  223. // flag isn't enabled.
  224. supportsTopLevelAwait: true,
  225. isServer,
  226. pagesDir,
  227. isDev: development,
  228. hasJsxRuntime,
  229. ...loaderOptions.caller
  230. }
  231. };
  232. // Babel does strict checks on the config so undefined is not allowed
  233. if (typeof options.target === "undefined") {
  234. delete options.target;
  235. }
  236. Object.defineProperty(options.caller, "onWarning", {
  237. enumerable: false,
  238. writable: false,
  239. value: (reason)=>{
  240. if (!(reason instanceof Error)) {
  241. reason = new Error(reason);
  242. }
  243. this.emitWarning(reason);
  244. }
  245. });
  246. const loadedOptions = (0, _core).loadOptions(options);
  247. const config = (0, _util).consumeIterator((0, _coreLibConfig).default(loadedOptions));
  248. return config;
  249. }
  250. /**
  251. * Each key returned here corresponds with a Babel config that can be shared.
  252. * The conditions of permissible sharing between files is dependent on specific
  253. * file attributes and Next.js compiler states: `CharacteristicsGermaneToCaching`.
  254. */ function getCacheKey(cacheCharacteristics) {
  255. const { isServer , isPageFile , isNextDist , hasModuleExports , fileExt } = cacheCharacteristics;
  256. const flags = 0 | (isServer ? 0b0001 : 0) | (isPageFile ? 0b0010 : 0) | (isNextDist ? 0b0100 : 0) | (hasModuleExports ? 0b1000 : 0);
  257. return fileExt + flags;
  258. }
  259. const configCache = new Map();
  260. const configFiles = new Set();
  261. //# sourceMappingURL=get-config.js.map