Guest User

Untitled

a guest
Apr 25th, 2018
84
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.63 KB | None | 0 0
  1. const { readdirSync } = require('fs');
  2. const { parse, resolve, dirname, format } = require('path');
  3.  
  4. function interpolate(template, context) {
  5. return template.replace(/\[(\w+)\]/g, (_, key) => context[key] || key);
  6. }
  7.  
  8. function isNodeModule(filename) {
  9. return !filename.startsWith('.');
  10. }
  11.  
  12. /*
  13. * babel-plugin-alt-import-require
  14. *
  15. * Example
  16. * plugins: [['babel-plugin-alt-import-require', { alt: '[name].mobile[ext]' }], ...otherPlugins]
  17. *
  18. * File structure
  19. * code
  20. * \
  21. * |_ components
  22. * | \
  23. * | |_ App.js
  24. * | |_ App.mobile.js
  25. * |
  26. * |_ containers
  27. * \
  28. * |_ Main.js
  29. *
  30. * Main.js
  31. * ```
  32. * import App from '../components/App';
  33. * // or
  34. * const App = require('../components/App');
  35. * ```
  36. *
  37. * If you're using the plugin after babel has run Main.js would look like this
  38. *
  39. * Main.js
  40. * ```
  41. * import App from '/code/components/App.mobile.js';
  42. * // or
  43. * const App = require('/code/components/App.mobile.js'');
  44. * ```
  45. */
  46.  
  47. // make cache 'global' to all instances of the plugin
  48. const cache = new Map();
  49.  
  50. module.exports = function(babel) {
  51. const { types: t } = babel;
  52.  
  53. function getAltFile(value, state) {
  54. const { alt } = state.opts;
  55. const filename = state.file.opts.filename;
  56.  
  57. // if the required/imported file is a node module or
  58. // there is no alt option bail out
  59. if (isNodeModule(value) || !alt) return null;
  60.  
  61. // get the absolute path the file being processed using the
  62. // node resolution algo to handle index.js files
  63. const resolved = require.resolve(resolve(dirname(filename), value));
  64.  
  65. const path = parse(resolved);
  66. const altFile = interpolate(alt, path);
  67.  
  68. // if the file being processed is the alt file bail out
  69. if (path.base === altFile) {
  70. return null;
  71. }
  72.  
  73. let files;
  74.  
  75. // check the cache to see if the dir has been processed before
  76. if (!cache.has(path.dir)) {
  77. files = readdirSync(path.dir);
  78. cache.set(path.dir, files);
  79. } else {
  80. files = cache.get(path.dir);
  81. }
  82.  
  83. const hasAltFile = files.includes(altFile);
  84.  
  85. return hasAltFile ? format({ ...path, base: altFile }) : null;
  86. }
  87.  
  88. return {
  89. name: 'alt-import-require',
  90. visitor: {
  91. ImportDeclaration(path, state) {
  92. const altFile = getAltFile(path.node.source.value, state);
  93.  
  94. if (altFile) {
  95. path.node.source.value = altFile;
  96. }
  97. },
  98. CallExpression(path, state) {
  99. if (t.isIdentifier(path.node.callee, { name: 'require' })) {
  100. const altFile = getAltFile(path.node.arguments[0].value, state);
  101.  
  102. if (altFile) {
  103. path.node.arguments[0].value = altFile;
  104. }
  105. }
  106. },
  107. },
  108. };
  109. };
Add Comment
Please, Sign In to add comment