index.js 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. "use strict";
  2. var _postcss = require("postcss");
  3. var _postcss2 = _interopRequireDefault(_postcss);
  4. var _lodash = require("lodash.camelcase");
  5. var _lodash2 = _interopRequireDefault(_lodash);
  6. var _genericNames = require("generic-names");
  7. var _genericNames2 = _interopRequireDefault(_genericNames);
  8. var _unquote = require("./unquote");
  9. var _unquote2 = _interopRequireDefault(_unquote);
  10. var _parser = require("./css-loader-core/parser");
  11. var _parser2 = _interopRequireDefault(_parser);
  12. var _loader = require("./css-loader-core/loader");
  13. var _loader2 = _interopRequireDefault(_loader);
  14. var _generateScopedName = require("./generateScopedName");
  15. var _generateScopedName2 = _interopRequireDefault(_generateScopedName);
  16. var _saveJSON = require("./saveJSON");
  17. var _saveJSON2 = _interopRequireDefault(_saveJSON);
  18. var _behaviours = require("./behaviours");
  19. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  20. function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
  21. const PLUGIN_NAME = "postcss-modules";
  22. function getDefaultScopeBehaviour(opts) {
  23. if (opts.scopeBehaviour && (0, _behaviours.isValidBehaviour)(opts.scopeBehaviour)) {
  24. return opts.scopeBehaviour;
  25. }
  26. return _behaviours.behaviours.LOCAL;
  27. }
  28. function getScopedNameGenerator(opts) {
  29. const scopedNameGenerator = opts.generateScopedName || _generateScopedName2.default;
  30. if (typeof scopedNameGenerator === "function") return scopedNameGenerator;
  31. return (0, _genericNames2.default)(scopedNameGenerator, {
  32. context: process.cwd(),
  33. hashPrefix: opts.hashPrefix
  34. });
  35. }
  36. function getLoader(opts, plugins) {
  37. const root = typeof opts.root === "undefined" ? "/" : opts.root;
  38. return typeof opts.Loader === "function" ? new opts.Loader(root, plugins) : new _loader2.default(root, plugins);
  39. }
  40. function isGlobalModule(globalModules, inputFile) {
  41. return globalModules.some(regex => inputFile.match(regex));
  42. }
  43. function getDefaultPluginsList(opts, inputFile) {
  44. const globalModulesList = opts.globalModulePaths || null;
  45. const exportGlobals = opts.exportGlobals || false;
  46. const defaultBehaviour = getDefaultScopeBehaviour(opts);
  47. const generateScopedName = getScopedNameGenerator(opts);
  48. if (globalModulesList && isGlobalModule(globalModulesList, inputFile)) {
  49. return (0, _behaviours.getDefaultPlugins)({
  50. behaviour: _behaviours.behaviours.GLOBAL,
  51. generateScopedName,
  52. exportGlobals
  53. });
  54. }
  55. return (0, _behaviours.getDefaultPlugins)({
  56. behaviour: defaultBehaviour,
  57. generateScopedName,
  58. exportGlobals
  59. });
  60. }
  61. function isOurPlugin(plugin) {
  62. return plugin.postcssPlugin === PLUGIN_NAME;
  63. }
  64. function dashesCamelCase(string) {
  65. return string.replace(/-+(\w)/g, (_, firstLetter) => firstLetter.toUpperCase());
  66. }
  67. module.exports = (opts = {}) => {
  68. return {
  69. postcssPlugin: PLUGIN_NAME,
  70. OnceExit(css, { result }) {
  71. return _asyncToGenerator(function* () {
  72. const getJSON = opts.getJSON || _saveJSON2.default;
  73. const inputFile = css.source.input.file;
  74. const pluginList = getDefaultPluginsList(opts, inputFile);
  75. const resultPluginIndex = result.processor.plugins.findIndex(function (plugin) {
  76. return isOurPlugin(plugin);
  77. });
  78. if (resultPluginIndex === -1) {
  79. throw new Error('Plugin missing from options.');
  80. }
  81. const earlierPlugins = result.processor.plugins.slice(0, resultPluginIndex);
  82. const loaderPlugins = [...earlierPlugins, ...pluginList];
  83. const loader = getLoader(opts, loaderPlugins);
  84. const fetcher = function fetcher(file, relativeTo, depTrace) {
  85. const unquoteFile = (0, _unquote2.default)(file);
  86. const resolvedResult = typeof opts.resolve === 'function' && opts.resolve(unquoteFile);
  87. const resolvedFile = resolvedResult instanceof Promise ? resolvedResult : Promise.resolve(resolvedResult);
  88. return resolvedFile.then(function (f) {
  89. return loader.fetch.call(loader, `"${f || unquoteFile}"`, relativeTo, depTrace);
  90. });
  91. };
  92. const parser = new _parser2.default(fetcher);
  93. yield (0, _postcss2.default)([...pluginList, parser.plugin()]).process(css, {
  94. from: inputFile
  95. });
  96. const out = loader.finalSource;
  97. if (out) css.prepend(out);
  98. if (opts.localsConvention) {
  99. const isFunc = typeof opts.localsConvention === "function";
  100. parser.exportTokens = Object.entries(parser.exportTokens).reduce(function (tokens, [className, value]) {
  101. if (isFunc) {
  102. tokens[opts.localsConvention(className, value, inputFile)] = value;
  103. return tokens;
  104. }
  105. switch (opts.localsConvention) {
  106. case "camelCase":
  107. tokens[className] = value;
  108. tokens[(0, _lodash2.default)(className)] = value;
  109. break;
  110. case "camelCaseOnly":
  111. tokens[(0, _lodash2.default)(className)] = value;
  112. break;
  113. case "dashes":
  114. tokens[className] = value;
  115. tokens[dashesCamelCase(className)] = value;
  116. break;
  117. case "dashesOnly":
  118. tokens[dashesCamelCase(className)] = value;
  119. break;
  120. }
  121. return tokens;
  122. }, {});
  123. }
  124. result.messages.push({
  125. type: "export",
  126. plugin: "postcss-modules",
  127. exportTokens: parser.exportTokens
  128. });
  129. // getJSON may return a promise
  130. return getJSON(css.source.input.file, parser.exportTokens, result.opts.to);
  131. })();
  132. }
  133. };
  134. };
  135. module.exports.postcss = true;