index.js 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. 'use strict';
  2. const { extname } = require('path');
  3. function namedAssetImportPlugin({ types: t }) {
  4. const visited = new WeakSet();
  5. function generateNewSourcePath(loaderMap, moduleName, sourcePath) {
  6. const ext = extname(sourcePath).substr(1);
  7. const extMap = loaderMap[ext];
  8. return extMap[moduleName]
  9. ? extMap[moduleName].replace(/\[path\]/, sourcePath)
  10. : sourcePath;
  11. }
  12. function replaceMatchingSpecifiers(path, loaderMap, callback) {
  13. const sourcePath = path.node.source.value;
  14. const ext = extname(sourcePath).substr(1);
  15. if (visited.has(path.node) || sourcePath.indexOf('!') !== -1) {
  16. return;
  17. }
  18. if (loaderMap[ext]) {
  19. path.replaceWithMultiple(
  20. path.node.specifiers.map(specifier => {
  21. const newSpecifier = callback(specifier, sourcePath);
  22. visited.add(newSpecifier);
  23. return newSpecifier;
  24. })
  25. );
  26. }
  27. }
  28. return {
  29. visitor: {
  30. ExportNamedDeclaration(path, { opts: { loaderMap } }) {
  31. if (!path.node.source) {
  32. return;
  33. }
  34. replaceMatchingSpecifiers(path, loaderMap, (specifier, sourcePath) => {
  35. if (t.isExportDefaultSpecifier(specifier)) {
  36. return t.exportDeclaration(
  37. [t.exportDefaultSpecifier(t.identifier(specifier.local.name))],
  38. t.stringLiteral(sourcePath)
  39. );
  40. }
  41. return t.exportNamedDeclaration(
  42. null,
  43. [
  44. t.exportSpecifier(
  45. t.identifier(specifier.local.name),
  46. t.identifier(specifier.exported.name)
  47. ),
  48. ],
  49. t.stringLiteral(
  50. generateNewSourcePath(loaderMap, specifier.local.name, sourcePath)
  51. )
  52. );
  53. });
  54. },
  55. ImportDeclaration(path, { opts: { loaderMap } }) {
  56. replaceMatchingSpecifiers(path, loaderMap, (specifier, sourcePath) => {
  57. if (t.isImportDefaultSpecifier(specifier)) {
  58. return t.importDeclaration(
  59. [t.importDefaultSpecifier(t.identifier(specifier.local.name))],
  60. t.stringLiteral(sourcePath)
  61. );
  62. }
  63. return t.importDeclaration(
  64. [
  65. t.importSpecifier(
  66. t.identifier(specifier.local.name),
  67. t.identifier(specifier.imported.name)
  68. ),
  69. ],
  70. t.stringLiteral(
  71. generateNewSourcePath(
  72. loaderMap,
  73. specifier.imported.name,
  74. sourcePath
  75. )
  76. )
  77. );
  78. });
  79. },
  80. },
  81. };
  82. }
  83. module.exports = namedAssetImportPlugin;