【前端工程化】对于@babel/traverse和AST的研究

通过AST解析reExport文件,生成组件和工具路径的json文件

reExport文件

export { default as Button } from './components/Button/';
export { default as Checkbox, CheckboxGroup } from './components/Checkbox';
export { default as Chip } from './components/Chip';
export { default as DatePicker } from './components/DatePicker';
export { default as Dialog } from './components/Dialog';
export { default as DragDropFileUpload } from './components/DragDropFileUpload';
export { default as DropdownButton } from './components/DropdownButton/';
...

 

path.js (可以放到其他文件里执行)

const parser = require('@babel/parser');
const traverse = require('@babel/traverse').default;

const { writeFile, readFileSync } = require('fs');
const { resolve } = require('path');

const indexFile = readFileSync(resolve(__dirname, './index.js'), 'utf-8');
const ast = parser.parse(indexFile, {
  sourceType: 'module',
  plugins: ['jsx'],
});
const pathObj = {};
let route = null;

traverse(ast, {
  enter(path) {
    if (path.node.type === 'ExportSpecifier') {
      const {
        node: {
          exported: { name },
        },
      } = path;
      pathObj[name] =
        route[route.length - 1] === '/'
          ? route.substring(0, route.length - 1)
          : route;
    }
    if (path.node.type === 'ExportNamedDeclaration') {
      const {
        node: {
          source: { value },
        },
      } = path;
      route = value.replace('./', '');
    }
    if (
      path.node.type.indexOf('ExportSpecifier') < 0 &&
      path.node.type === 'ExportAllDeclaration'
    ) {
      const {
        node: {
          source: { value },
        },
      } = path;
      route = value;
      let rootRoute = null;
      const reExportFile = readFileSync(
        resolve(__dirname, `${route}/index.js`),
        'utf-8'
      );
      const reExportAST = parser.parse(reExportFile, {
        sourceType: 'module',
        plugins: ['jsx'],
      });
      traverse(reExportAST, {
        enter(path) {
          if (path.node.type === 'ExportSpecifier') {
            const {
              node: {
                exported: { name },
              },
            } = path;
            pathObj[name] =
              rootRoute[rootRoute.length - 1] === '/'
                ? rootRoute.substring(0, rootRoute.length - 1)
                : rootRoute;
          }
          if (path.node.type === 'ExportNamedDeclaration') {
            rootRoute = route;
            const {
              node: {
                source: { value },
              },
            } = path;
            rootRoute = `${rootRoute.replace('./', '')}${value.substring(1)}`;
          }
        },
      });
    }
  },
});

writeFile(
  resolve(__dirname, 'paths.json'),
  JSON.stringify(pathObj, null, '\t'),
  err => {
    if (err) throw new Error();
  }
);

path.json 放在src目录下

{
    "CoreConfig": "config",
    "prefixIt": "utilities",
    "errorMessage": "utilities",
    "useClickOutside": "hooks/useClickOutside",
    "useFocus": "hooks/useFocus",
    "useForceUpdate": "hooks/useForceUpdate",
    "useForkRef": "hooks/useForkRef",
    "usePrevious": "hooks/usePrevious",
    "useResizeObserver": "hooks/useResizeObserver",
    "useEventCallback": "hooks/useEventCallback",
    "useTabsLoop": "hooks/useTabsLoop",
    "useUncontrolled": "hooks/useUncontrolled",
    "useIsomorphicLayoutEffect": "hooks/useIsomorphicLayoutEffect",
    "Button": "components/Button",
    "Checkbox": "components/Checkbox",
    "CheckboxGroup": "components/Checkbox",
    "Chip": "components/Chip",
    "DatePicker": "components/DatePicker",
    "Dialog": "components/Dialog",
    "DragDropFileUpload": "components/DragDropFileUpload",
    "DropdownButton": "components/DropdownButton",
    "DropdownMenu": "components/DropdownMenu",
    "DropdownItem": "components/DropdownMenu",
    "Error": "components/Error",
    "FieldPicker": "components/FieldPicker",
    "FormControl": "components/FormControl",
    "FormInput": "components/FormInput",
    "Container": "components/Grid",
    "Row": "components/Grid",
    "Col": "components/Grid",
    "Visible": "components/Grid",
    "Hidden": "components/Grid",
    "ClearFix": "components/Grid",
    "ScreenClassRender": "components/Grid",
    "ScreenClassProvider": "components/Grid",
    "useScreenClass": "components/Grid",
    "GridLoader": "components/GridLoader",
    "Icon": "components/Icon",
    "IconDefinitions": "components/Icon",
    "IconNames": "components/Icon",
    "InlineMessageBlock": "components/InlineMessageBlock",
    "KeyboardCapture": "components/KeyboardCapture",
    "Link": "components/Link",
    "Matomo": "components/Matomo",
    "matomoMiddleware": "components/Matomo",
    "MatomoContext": "components/Matomo",
    "MatomoProvider": "components/Matomo",
    "useMatomo": "components/Matomo",
    "List": "components/List",
    "Item": "components/List",
    "ItemDivider": "components/List",
    "Modal": "components/Modal",
    "NavigableList": "components/NavigableList",
    "Popover": "components/PopoverModal",
    "PopoverDialog": "components/PopoverDialog",
    "ProgressSpinner": "components/ProgressSpinner",
    "Radio": "components/Radio",
    "RadioGroup": "components/Radio",
    "RedirectConfirmation": "components/RedirectConfirmation",
    "ReduxFormHelpers": "components/ReduxFormHelpers",
    "RichTextEditor": "components/RichTextEditor",
    "Select": "components/Select",
    "SplitButton": "components/SplitButton",
    "StyledIcon": "components/StyledIcon",
    "Svg": "components/Svg",
    "Tabs": "components/Tabs",
    "Tab": "components/Tabs",
    "TabList": "components/Tabs",
    "TabPanel": "components/Tabs",
    "Tags": "components/Tags",
    "TextArea": "components/TextArea",
    "TextInput": "components/TextInput",
    "TimePicker": "components/TimePicker",
    "toast": "components/ToastContainer",
    "ToastContainer": "components/ToastContainer",
    "Toggle": "components/Toggle",
    "Tooltip": "components/Tooltip",
    "Fade": "components/Transition",
    "Typeahead": "components/Typeahead",
    "TypeaheadBuilder": "components/TypeaheadBuilder",
    "VectorGraphic": "components/VectorGraphic",
    "ViewAllModal": "components/ViewAllModal",
    "ViewAll": "components/ViewAll",
    "Truncate": "components/Truncate",
    "Skeleton": "components/Skeleton"
}

读取JSON文件并使用

const data = readFileSync(
  path.resolve(
    __dirname,
    '../node_modules/react-core/dist/esm/paths.json'
  ),
  'utf-8'
);

  const libraryObject = JSON.parse(data);

 

posted @ 2022-01-20 10:03  一路向北√  阅读(723)  评论(0编辑  收藏  举报

web应用开发&研究 -

业精于勤而荒于嬉。

工作,使我快乐。


Font Awesome | Respond.js | Bootstrap中文网