plugins.js 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", {
  3. value: true
  4. });
  5. exports.getPostCssPlugins = getPostCssPlugins;
  6. var _chalk = _interopRequireDefault(require("next/dist/compiled/chalk"));
  7. var _findConfig = require("../../../../../lib/find-config");
  8. function _interopRequireDefault(obj) {
  9. return obj && obj.__esModule ? obj : {
  10. default: obj
  11. };
  12. }
  13. const genericErrorText = "Malformed PostCSS Configuration";
  14. function getError_NullConfig(pluginName) {
  15. return `${_chalk.default.red.bold("Error")}: Your PostCSS configuration for '${pluginName}' cannot have ${_chalk.default.bold("null")} configuration.\nTo disable '${pluginName}', pass ${_chalk.default.bold("false")}, otherwise, pass ${_chalk.default.bold("true")} or a configuration object.`;
  16. }
  17. function isIgnoredPlugin(pluginPath) {
  18. const ignoredRegex = /(?:^|[\\/])(postcss-modules-values|postcss-modules-scope|postcss-modules-extract-imports|postcss-modules-local-by-default|postcss-modules)(?:[\\/]|$)/i;
  19. const match = ignoredRegex.exec(pluginPath);
  20. if (match == null) {
  21. return false;
  22. }
  23. const plugin = match.pop();
  24. console.warn(`${_chalk.default.yellow.bold("Warning")}: Please remove the ${_chalk.default.underline(plugin)} plugin from your PostCSS configuration. ` + `This plugin is automatically configured by Next.js.\n` + "Read more: https://nextjs.org/docs/messages/postcss-ignored-plugin");
  25. return true;
  26. }
  27. const createLazyPostCssPlugin = (fn)=>{
  28. let result = undefined;
  29. const plugin = (...args)=>{
  30. if (result === undefined) result = fn();
  31. if (result.postcss === true) {
  32. return result(...args);
  33. } else if (result.postcss) {
  34. return result.postcss;
  35. }
  36. return result;
  37. };
  38. plugin.postcss = true;
  39. return plugin;
  40. };
  41. async function loadPlugin(dir, pluginName, options) {
  42. if (options === false || isIgnoredPlugin(pluginName)) {
  43. return false;
  44. }
  45. if (options == null) {
  46. console.error(getError_NullConfig(pluginName));
  47. throw new Error(genericErrorText);
  48. }
  49. const pluginPath = require.resolve(pluginName, {
  50. paths: [
  51. dir
  52. ]
  53. });
  54. if (isIgnoredPlugin(pluginPath)) {
  55. return false;
  56. } else if (options === true) {
  57. return createLazyPostCssPlugin(()=>require(pluginPath));
  58. } else {
  59. if (typeof options === "object" && Object.keys(options).length === 0) {
  60. return createLazyPostCssPlugin(()=>require(pluginPath));
  61. }
  62. return createLazyPostCssPlugin(()=>require(pluginPath)(options));
  63. }
  64. }
  65. function getDefaultPlugins(supportedBrowsers, disablePostcssPresetEnv) {
  66. return [
  67. require.resolve("next/dist/compiled/postcss-flexbugs-fixes"),
  68. disablePostcssPresetEnv ? false : [
  69. require.resolve("next/dist/compiled/postcss-preset-env"),
  70. {
  71. browsers: supportedBrowsers != null ? supportedBrowsers : [
  72. "defaults"
  73. ],
  74. autoprefixer: {
  75. // Disable legacy flexbox support
  76. flexbox: "no-2009"
  77. },
  78. // Enable CSS features that have shipped to the
  79. // web platform, i.e. in 2+ browsers unflagged.
  80. stage: 3,
  81. features: {
  82. "custom-properties": false
  83. }
  84. },
  85. ],
  86. ].filter(Boolean);
  87. }
  88. async function getPostCssPlugins(dir, supportedBrowsers, disablePostcssPresetEnv = false) {
  89. let config = await (0, _findConfig).findConfig(dir, "postcss");
  90. if (config == null) {
  91. config = {
  92. plugins: getDefaultPlugins(supportedBrowsers, disablePostcssPresetEnv)
  93. };
  94. }
  95. if (typeof config === "function") {
  96. throw new Error(`Your custom PostCSS configuration may not export a function. Please export a plain object instead.\n` + "Read more: https://nextjs.org/docs/messages/postcss-function");
  97. }
  98. // Warn user about configuration keys which are not respected
  99. const invalidKey = Object.keys(config).find((key)=>key !== "plugins");
  100. if (invalidKey) {
  101. console.warn(`${_chalk.default.yellow.bold("Warning")}: Your PostCSS configuration defines a field which is not supported (\`${invalidKey}\`). ` + `Please remove this configuration value.`);
  102. }
  103. // Enforce the user provided plugins if the configuration file is present
  104. let plugins = config.plugins;
  105. if (plugins == null || typeof plugins !== "object") {
  106. throw new Error(`Your custom PostCSS configuration must export a \`plugins\` key.`);
  107. }
  108. if (!Array.isArray(plugins)) {
  109. // Capture variable so TypeScript is happy
  110. const pc = plugins;
  111. plugins = Object.keys(plugins).reduce((acc, curr)=>{
  112. const p = pc[curr];
  113. if (typeof p === "undefined") {
  114. console.error(getError_NullConfig(curr));
  115. throw new Error(genericErrorText);
  116. }
  117. acc.push([
  118. curr,
  119. p
  120. ]);
  121. return acc;
  122. }, []);
  123. }
  124. const parsed = [];
  125. plugins.forEach((plugin)=>{
  126. if (plugin == null) {
  127. console.warn(`${_chalk.default.yellow.bold("Warning")}: A ${_chalk.default.bold("null")} PostCSS plugin was provided. This entry will be ignored.`);
  128. } else if (typeof plugin === "string") {
  129. parsed.push([
  130. plugin,
  131. true
  132. ]);
  133. } else if (Array.isArray(plugin)) {
  134. const pluginName = plugin[0];
  135. const pluginConfig = plugin[1];
  136. if (typeof pluginName === "string" && (typeof pluginConfig === "boolean" || typeof pluginConfig === "object" || typeof pluginConfig === "string")) {
  137. parsed.push([
  138. pluginName,
  139. pluginConfig
  140. ]);
  141. } else {
  142. if (typeof pluginName !== "string") {
  143. console.error(`${_chalk.default.red.bold("Error")}: A PostCSS Plugin must be provided as a ${_chalk.default.bold("string")}. Instead, we got: '${pluginName}'.\n` + "Read more: https://nextjs.org/docs/messages/postcss-shape");
  144. } else {
  145. console.error(`${_chalk.default.red.bold("Error")}: A PostCSS Plugin was passed as an array but did not provide its configuration ('${pluginName}').\n` + "Read more: https://nextjs.org/docs/messages/postcss-shape");
  146. }
  147. throw new Error(genericErrorText);
  148. }
  149. } else if (typeof plugin === "function") {
  150. console.error(`${_chalk.default.red.bold("Error")}: A PostCSS Plugin was passed as a function using require(), but it must be provided as a ${_chalk.default.bold("string")}.\nRead more: https://nextjs.org/docs/messages/postcss-shape`);
  151. throw new Error(genericErrorText);
  152. } else {
  153. console.error(`${_chalk.default.red.bold("Error")}: An unknown PostCSS plugin was provided (${plugin}).\n` + "Read more: https://nextjs.org/docs/messages/postcss-shape");
  154. throw new Error(genericErrorText);
  155. }
  156. });
  157. const resolved = await Promise.all(parsed.map((p)=>loadPlugin(dir, p[0], p[1])));
  158. const filtered = resolved.filter(Boolean);
  159. return filtered;
  160. }
  161. //# sourceMappingURL=plugins.js.map