transform.js 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. const path = require('path')
  2. const BASE_PATH = 'frontend/js/'
  3. function getRelativePath(importPath, filePath) {
  4. // Ignore existing relative paths
  5. if (importPath.startsWith('.')) {
  6. return importPath
  7. }
  8. // Ignore npm deps (should be absolute)
  9. if (
  10. importPath.startsWith('crypto-js') ||
  11. importPath.startsWith('moment') ||
  12. importPath.startsWith('algoliasearch') ||
  13. importPath.startsWith('qrcode')
  14. ) {
  15. return importPath
  16. }
  17. // Ignore aliased paths (handled specially by webpack)
  18. if (
  19. importPath.startsWith('libs/') ||
  20. importPath.startsWith('ace/') ||
  21. importPath.startsWith('fineuploader')
  22. ) {
  23. return importPath
  24. }
  25. const relativePath = path.relative(filePath, `${BASE_PATH}/${importPath}/`)
  26. // Strip leading dots if importing at same level, because path.relative
  27. // likes to use ../my-file.js instead of ./my-file.js
  28. if (/^\.{2}\/\w/.test(relativePath)) {
  29. return relativePath.substring(1)
  30. } else {
  31. return relativePath.substring(3)
  32. }
  33. }
  34. export default function(file, api) {
  35. const j = api.jscodeshift
  36. const filePath = file.path
  37. return j(file.source)
  38. .find(j.CallExpression, {
  39. callee: { name: 'define' }
  40. })
  41. .replaceWith(node => {
  42. const defineArgs = node.get('arguments', 0)
  43. const deps = defineArgs.get('elements')
  44. // Ignore files with no deps
  45. if (!deps.value) {
  46. return node.value
  47. }
  48. const elems = deps.map(e => {
  49. return j.literal(getRelativePath(e.node.value, filePath))
  50. })
  51. const newDeps = j.arrayExpression(elems)
  52. const callee = node.get('callee').value
  53. const cb = node.get('arguments', 1).value
  54. return j.callExpression(callee, [newDeps, cb])
  55. })
  56. .toSource()
  57. }