transform.js 1.7 KB

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