convert SWC to Babel AST

Overview

SWC-to-babel NPM version Build Status Coverage Status

Convert SWC JavaScript AST to Babel AST.

To use SWC parser with babel tools like:

The thing is @babel/parser has a a little differences with swc standard:

  • File node exists;
  • Program instead of Module;
  • loc with line and column instead of span;
  • StringLiteral has no kind an hasEscape;
  • Identifier has no optional;
  • VariableDeclarator has no optional and definite;
  • etc...

swc-to-babel aims to smooth this differences.

Install

npm i swc-to-babel

Example

const swc = require('@swc/core');
const toBabel = require('swc-to-babel');
const traverse = require('@babel/traverse').default;

const ast = toBabel(swc.parse(`
    const f = ({a}) => a;
`));

traverse({
    ObjectProperty(path) {
        console.log(path.value.name);
        // output
        'a';
    },
});

License

MIT

Comments
  • Add an extra layer of testing using @babel/generator

    Add an extra layer of testing using @babel/generator

    Test cases can be faulty (this actually happened with the getters and setters PR) and the AST produced by this library may be invalid. The only real way to test if the AST is valid is to use @babel/generator to try to generate code from it.

    opened by Markos-Th09 15
  • The example in the README doesn't work without a second parameter

    The example in the README doesn't work without a second parameter

    Something which isn't mentioned in the docs is that the function needs to take a second argument. This argument is optionally the source code or an empty string if it isn't available. As it isn't necessarily required but it is good to pass I think it should be optional. Also I think there should be an api reference in the README.

    docs feature 
    opened by Markos-Th09 7
  • SWC-to-Babel crashes with the given file

    SWC-to-Babel crashes with the given file

    Firstly. thank you for this library. I came across this bug when testing it on a large project. When I try to convert swc AST of the given file to babel AST i get the following error:

    TypeError: Property object of MemberExpression expected node to be of a type ["Expression"] but instead got "TsAsExpression"
        at Object.validate (/Users/pulak.malhotra/intern/i18n/node_modules/@babel/types/lib/definitions/utils.js:131:11)
        at validateField (/Users/pulak.malhotra/intern/i18n/node_modules/@babel/types/lib/validators/validate.js:24:9)
        at validate (/Users/pulak.malhotra/intern/i18n/node_modules/@babel/types/lib/validators/validate.js:17:3)
        at NodePath._replaceWith (/Users/pulak.malhotra/intern/i18n/node_modules/@babel/traverse/lib/path/replacement.js:170:5)
        at NodePath.replaceWith (/Users/pulak.malhotra/intern/i18n/node_modules/@babel/traverse/lib/path/replacement.js:152:8)
        at module.exports.convertParenthesisExpression (/Users/pulak.malhotra/intern/i18n/node_modules/swc-to-babel/lib/swc/index.js:118:10)
        at enter (/Users/pulak.malhotra/intern/i18n/node_modules/swc-to-babel/lib/swc-to-babel.js:80:24)
        at NodePath._call (/Users/pulak.malhotra/intern/i18n/node_modules/@babel/traverse/lib/path/context.js:53:20)
        at NodePath.call (/Users/pulak.malhotra/intern/i18n/node_modules/@babel/traverse/lib/path/context.js:36:14)
        at NodePath.visit (/Users/pulak.malhotra/intern/i18n/node_modules/@babel/traverse/lib/path/context.js:100:31)
    

    Here is my source code that I am using to test it:

    import swc from '@swc/core';
    import toBabel from 'swc-to-babel';
    import { getExtension } from './utils.js';
    import fs from 'fs'
    import * as babel from '@babel/core'
    
    async function main() {
    const filename = "../eigen/src/palette/Theme.tsx"
    
    const code = fs.readFileSync(filename, {encoding: "utf8"}) 
    
    function getAstBabel(code, filename) {
      const { ast } = babel.transformSync(code, {
        filename,
        presets: [
          '@babel/preset-typescript',
          '@babel/preset-react',
          // '@babel/preset-flow',
        ],
        plugins: [['@babel/plugin-proposal-decorators', { legacy: true }]],
        code: false,
        ast: true,
      });
      return ast
    }
    
    let syntax: "ecmascript" | "typescript";
    if (getExtension(filename) === "js" || getExtension(filename) === "jsx") {
      syntax = "ecmascript"
    } else {
      syntax = "typescript"
    }
    
    const swcStuff =  await swc.parse(code, {
      syntax,
      tsx: true,
      jsx: true,
      decorators: true,
      topLevelAwait: true,
      dynamicImport: true,
    
    });
    // console.log(swcStuff)
    const babelstuff = getAstBabel(code, filename);
    fs.writeFileSync("babelAST.json", JSON.stringify(babelstuff, null, 4))
    
    
    const ast = toBabel(swcStuff, code);
    fs.writeFileSync("swcAST.json", JSON.stringify(babelstuff, null , 4))
    }
    main()
    

    I will try to fix this issue but it might take some time as I am new to the code base and not familiar with SWC or babel AST that much.

    file contents

    import { THEME_V2, THEME_V3 } from "@artsy/palette-tokens"
    import _ from "lodash"
    import React, { useContext } from "react"
    import { ThemeContext, ThemeProvider } from "styled-components/native"
    
    /**
     * All of the config for the Artsy theming system, based on the
     * design system from our design team:
     * https://www.notion.so/artsy/Master-Library-810612339f474d0997fe359af4285c56
     */
    
    import { SpacingUnit as SpacingUnitV2 } from "@artsy/palette-tokens/dist/themes/v2"
    import {
      Color as ColorV3BeforeDevPurple,
      SpacingUnit as SpacingUnitV3Numbers,
    } from "@artsy/palette-tokens/dist/themes/v3"
    import {
      TextTreatment as TextTreatmentWithUnits,
      TextVariant as TextVariantV3,
    } from "@artsy/palette-tokens/dist/typography/v3"
    
    type SpacingUnitV3 = `${SpacingUnitV3Numbers}`
    export type SpacingUnit = SpacingUnitV2 | SpacingUnitV3
    export type Color =
      | ColorV3BeforeDevPurple
      | "devpurple"
      | "yellow150"
      | "yellow100"
      | "yellow30"
      | "yellow10"
      | "orange10"
      | "orange100" // yellows and orange are temporary, until we add them to palette-tokens
      // v5 stuff
      | "appBackground"
      | "appForeground"
    export { SpacingUnitV2, SpacingUnitV3 }
    export { TextVariantV3 }
    
    const {
      breakpoints: _eigenDoesntCareAboutBreakpoints,
      mediaQueries: _eigenDoesntCareAboutMediaQueries,
      grid: _eigenDoesntCareAboutGrid,
      textVariants: textVariantsWithUnits,
      space: spaceNumbers,
      ...eigenUsefulTHEME_V3
    } = THEME_V3
    
    // this function is converting the space values that come from palette-tokens
    // from a string `"120px"` to a number `120`.
    const fixSpaceUnitsV2 = (
      units: typeof THEME_V2.space
    ): {
      0.3: number
      0.5: number
      1: number
      1.5: number
      2: number
      3: number
      4: number
      5: number
      6: number
      9: number
      12: number
      18: number
    } => {
      let fixed = units
    
      fixed = _.mapValues(fixed, (stringValueWithPx) => {
        const justStringValue = _.split(stringValueWithPx, "px")[0]
        const numberValue = parseInt(justStringValue, 10)
        return numberValue
      }) as any
    
      return fixed as any
    }
    
    // this function is converting the space values that come from palette-tokens
    // from a string `"120px"` to a number `120`, and the key values
    // from a number `0.5` to a string `"0.5"`.
    const fixSpaceUnitsV3 = (
      units: typeof spaceNumbers
    ): {
      "0.5": number
      "1": number
      "2": number
      "4": number
      "6": number
      "12": number
    } => {
      let fixed = units
    
      fixed = _.mapKeys(fixed, (_value, numberKey) => `${numberKey}`) as any
    
      fixed = _.mapValues(fixed, (stringValueWithPx) => {
        const justStringValue = _.split(stringValueWithPx, "px")[0]
        const numberValue = parseInt(justStringValue, 10)
        return numberValue
      }) as any
    
      return fixed as any
    }
    
    // this function is just adding a dev color, `devpurple`
    const fixColorV3 = (
      colors: typeof eigenUsefulTHEME_V3.colors
    ): typeof eigenUsefulTHEME_V3.colors & { devpurple: string } => {
      const ourColors = colors as any
      ourColors.devpurple = "#6E1EFF"
      ourColors.yellow150 = "#A47A0F"
      ourColors.yellow100 = "#A85F00"
      ourColors.yellow30 = "#FAE7BA"
      ourColors.yellow10 = "#F6EFE5"
      ourColors.orange10 = "#FCF7F3"
      ourColors.orange150 = "#A8501C"
      return colors as any
    }
    
    export interface TextTreatment {
      fontSize: number
      lineHeight: number
      letterSpacing?: number
    }
    
    // this function is removing the `px` and `em` suffix and making the values into numbers
    const fixTextTreatments = (
      variantsWithUnits: Record<"xxl" | "xl" | "lg" | "md" | "sm" | "xs", TextTreatmentWithUnits>
    ): Record<TextVariantV3, TextTreatment> => {
      const textTreatments = _.mapValues(variantsWithUnits, (treatmentWithUnits) => {
        const newTreatment = {} as TextTreatment
        ;(
          [
            ["fontSize", "px"],
            ["lineHeight", "px"],
            ["letterSpacing", "em"],
          ] as Array<[keyof TextTreatment, string]>
        ).forEach(([property, unit]) => {
          const originalValue = treatmentWithUnits[property]
          if (originalValue === undefined) {
            return undefined
          }
          const justStringValue = _.split(originalValue, unit)[0]
          const numberValue = parseInt(justStringValue, 10)
          newTreatment[property] = numberValue
        })
        return newTreatment
      })
      return textTreatments
    }
    
    const THEMES = {
      v2: {
        ...THEME_V2,
        fontFamily: {
          sans: {
            regular: { normal: "Unica77LL-Regular", italic: "Unica77LL-Italic" },
            medium: { normal: "Unica77LL-Medium", italic: "Unica77LL-MediumItalic" },
            semibold: { normal: null, italic: null },
          },
          serif: {
            regular: {
              normal: "ReactNativeAGaramondPro-Regular",
              italic: "ReactNativeAGaramondPro-Italic",
            },
            medium: { normal: null, italic: null },
            semibold: { normal: "ReactNativeAGaramondPro-Semibold", italic: null },
          },
        },
        fonts: { sans: "Unica77LL-Regular", serif: "ReactNativeAGaramondPro-Regular" },
        space: fixSpaceUnitsV2(THEME_V2.space),
      },
      v3: {
        ...eigenUsefulTHEME_V3,
        colors: fixColorV3(eigenUsefulTHEME_V3.colors),
        space: fixSpaceUnitsV3(spaceNumbers),
        fonts: {
          sans: {
            regular: "Unica77LL-Regular",
            italic: "Unica77LL-Italic",
            medium: "Unica77LL-Medium",
            mediumItalic: "Unica77LL-MediumItalic",
          },
        },
        textTreatments: fixTextTreatments(textVariantsWithUnits),
      },
      v5: {
        ...eigenUsefulTHEME_V3,
        colors: {
          ...fixColorV3(eigenUsefulTHEME_V3.colors),
          appBackground: "white",
          appForeground: "black",
        },
        space: fixSpaceUnitsV3(spaceNumbers),
        fonts: {
          sans: {
            regular: "Unica77LL-Regular",
            italic: "Unica77LL-Italic",
            medium: "Unica77LL-Medium",
            mediumItalic: "Unica77LL-MediumItalic",
          },
        },
        textTreatments: fixTextTreatments(textVariantsWithUnits),
      },
      v5dark: {
        ...eigenUsefulTHEME_V3,
        colors: {
          ...fixColorV3(eigenUsefulTHEME_V3.colors),
          appBackground: "black",
          appForeground: "white",
        },
        space: fixSpaceUnitsV3(spaceNumbers),
        fonts: {
          sans: {
            regular: "Unica77LL-Regular",
            italic: "Unica77LL-Italic",
            medium: "Unica77LL-Medium",
            mediumItalic: "Unica77LL-MediumItalic",
          },
        },
        textTreatments: fixTextTreatments(textVariantsWithUnits),
      },
    }
    
    export type ThemeV3Type = typeof THEMES.v3
    export type ThemeType = ThemeV3Type
    
    /**
     * Do not use this!! Use any the hooks instead!
     */
    export const themeProps = THEMES.v2
    
    const figureOutTheme = (theme: keyof typeof THEMES | ThemeType): ThemeType => {
      if (!_.isString(theme)) {
        return theme
      }
    
      // forcing v3 spaces, unless specifically requiring v2, in which case we use `spaceV2`
      const mergedSpacesV2WithV3OnTop = {
        ...THEMES.v2.space, // get the base v2
        ...THEMES.v3.space, // get the base v3 on top of that
        // now add the rest of the mappings
        "0.3": THEMES.v3.space["0.5"], // TODO-PALETTE-V3 replace all {0.3} and "0.3" with "0.5"
        "1.5": THEMES.v3.space["2"], // TODO-PALETTE-V3 replace all {1.5} and "1.5" with "2"
        "3": THEMES.v3.space["4"], // TODO-PALETTE-V3 replace all {3} and "3" with "4"
        "5": THEMES.v3.space["6"], // TODO-PALETTE-V3 replace all {5} and "5" with "6"
        "9": THEMES.v3.space["6"], // TODO-PALETTE-V3 replace all {9} and "9" with "6"
        "18": THEMES.v3.space["12"], // TODO-PALETTE-V3 replace all {18} and "18" with "12"
      }
      // TODO-PALETTE-V3 remove the mapping as the last TODO-PALETTE-V3 to be done for space
    
      if (theme === "v5") {
        return THEMES.v5
      }
      if (theme === "v5dark") {
        return THEMES.v5dark
      }
    
      return { ...THEMES.v3, space: mergedSpacesV2WithV3OnTop }
    }
    
    export const Theme: React.FC<{
      theme?: keyof typeof THEMES | ThemeType
    }> = ({ children, theme = "v3" }) => {
      const actualTheme = figureOutTheme(theme)
      return <ThemeProvider theme={actualTheme}>{children}</ThemeProvider>
    }
    
    interface ColorFuncOverload {
      (colorNumber: undefined): undefined
      (colorNumber: Color): string
      (colorNumber: Color | undefined): string | undefined
    }
    const color =
      (theme: ThemeType): ColorFuncOverload =>
      (colorName: any): any => {
        if (colorName === undefined) {
          return undefined
        }
        return (theme.colors as { [key: string]: string })[colorName as Color]
      }
    
    const space =
      (theme: ThemeType) =>
      (spaceName: SpacingUnitV2 | SpacingUnitV3): number =>
        theme.space[spaceName as SpacingUnitV3]
    
    export const useTheme = () => {
      const theme: ThemeType = useContext(ThemeContext)
    
      // if we are not wrapped in `<Theme>`, if we dev, throw error.
      // if we are in prod, we will default to v2 to avoid a crash.
      // if we are wrapped, then all good.
      if ((__DEV__ || __TEST__) && theme === undefined) {
        console.error(
          "You are trying to use the `Theme` but you have not wrapped your component/screen with `<Theme>`. Please wrap and try again."
        )
        throw new Error(
          "ThemeContext is not defined. Wrap your component with `<Theme>` and try again."
        )
      }
      const themeIfUnwrapped = THEMES.v3
    
      return {
        theme: theme ?? themeIfUnwrapped,
        color: color(theme ?? themeIfUnwrapped),
        space: space(theme ?? themeIfUnwrapped),
      }
    }
    
    export const isThemeV3 = (theme: ThemeType): theme is ThemeV3Type => theme.id === "v3"
    
    /**
     * Only use this if it's are absolutely neccessary, and only in tests.
     */
    // tslint:disable-next-line:variable-name
    export const _test_THEMES = THEMES
    
    
    MemberExpression needs a fixture 
    opened by MalhotraPulak 5
  • Fix parenthesized const assertion error

    Fix parenthesized const assertion error

    When parsing the following ts code with swc (options are { syntax: 'typescript' }) and then passing the result to swc-to-babel:

    const foo = ([1, 2] as const);
    

    I get the following error:

    TypeError: Property object of MemberExpression expected node to be of a type ["Expression","Super"] but instead got "TsConstAssertion"
    

    Here's the relevant part of the stack trace:

          at Object.validate (node_modules/@babel/types/src/definitions/utils.ts:138:11)
          at validate (node_modules/@babel/types/src/validators/validate.ts:32:9)
          at validateField (node_modules/@babel/types/src/validators/validate.ts:19:3)
          at NodePath._replaceWith (node_modules/@babel/traverse/lib/path/replacement.js:169:5)
          at NodePath.replaceWith (node_modules/@babel/traverse/lib/path/replacement.js:151:8)
          at Object.<anonymous>.module.exports.convertParenthesisExpression (node_modules/swc-to-babel/lib/swc/index.js:132:10)
          at enter (node_modules/swc-to-babel/lib/swc-to-babel.js:119:24)
          at NodePath._call (node_modules/@babel/traverse/lib/path/context.js:53:20)
          at NodePath.call (node_modules/@babel/traverse/lib/path/context.js:36:14)
          at NodePath.visit (node_modules/@babel/traverse/lib/path/context.js:100:31)
          at TraversalContext.visitQueue (node_modules/@babel/traverse/lib/context.js:105:16)
          at TraversalContext.visitSingle (node_modules/@babel/traverse/lib/context.js:79:19)
          at TraversalContext.visit (node_modules/@babel/traverse/lib/context.js:133:19)
          at traverseNode (node_modules/@babel/traverse/lib/traverse-node.js:24:17)
          at NodePath.visit (node_modules/@babel/traverse/lib/path/context.js:107:52)
          at TraversalContext.visitQueue (node_modules/@babel/traverse/lib/context.js:105:16)
          at TraversalContext.visitSingle (node_modules/@babel/traverse/lib/context.js:79:19)
          at TraversalContext.visit (node_modules/@babel/traverse/lib/context.js:133:19)
          at traverseNode (node_modules/@babel/traverse/lib/traverse-node.js:24:17)
          at NodePath.visit (node_modules/@babel/traverse/lib/path/context.js:107:52)
          at TraversalContext.visitQueue (node_modules/@babel/traverse/lib/context.js:105:16)
          at TraversalContext.visitSingle (node_modules/@babel/traverse/lib/context.js:79:19)
          at TraversalContext.visit (node_modules/@babel/traverse/lib/context.js:133:19)
          at traverseNode (node_modules/@babel/traverse/lib/traverse-node.js:24:17)
          at NodePath.visit (node_modules/@babel/traverse/lib/path/context.js:107:52)
          at TraversalContext.visitQueue (node_modules/@babel/traverse/lib/context.js:105:16)
          at TraversalContext.visitMultiple (node_modules/@babel/traverse/lib/context.js:74:17)
          at TraversalContext.visit (node_modules/@babel/traverse/lib/context.js:131:19)
          at traverseNode (node_modules/@babel/traverse/lib/traverse-node.js:24:17)
          at NodePath.visit (node_modules/@babel/traverse/lib/path/context.js:107:52)
          at TraversalContext.visitQueue (node_modules/@babel/traverse/lib/context.js:105:16)
          at TraversalContext.visitQueue (node_modules/@babel/traverse/lib/context.js:111:21)
          at TraversalContext.visitSingle (node_modules/@babel/traverse/lib/context.js:79:19)
          at TraversalContext.visit (node_modules/@babel/traverse/lib/context.js:133:19)
          at traverseNode (node_modules/@babel/traverse/lib/traverse-node.js:24:17)
          at NodePath.visit (node_modules/@babel/traverse/lib/path/context.js:107:52)
          at TraversalContext.visitQueue (node_modules/@babel/traverse/lib/context.js:105:16)
          at TraversalContext.visitMultiple (node_modules/@babel/traverse/lib/context.js:74:17)
          at TraversalContext.visit (node_modules/@babel/traverse/lib/context.js:131:19)
          at traverseNode (node_modules/@babel/traverse/lib/traverse-node.js:24:17)
          at NodePath.visit (node_modules/@babel/traverse/lib/path/context.js:107:52)
          at TraversalContext.visitQueue (node_modules/@babel/traverse/lib/context.js:105:16)
          at TraversalContext.visitSingle (node_modules/@babel/traverse/lib/context.js:79:19)
          at TraversalContext.visit (node_modules/@babel/traverse/lib/context.js:133:19)
          at traverseNode (node_modules/@babel/traverse/lib/traverse-node.js:24:17)
          at NodePath.visit (node_modules/@babel/traverse/lib/path/context.js:107:52)
          at TraversalContext.visitQueue (node_modules/@babel/traverse/lib/context.js:105:16)
          at TraversalContext.visitMultiple (node_modules/@babel/traverse/lib/context.js:74:17)
          at TraversalContext.visit (node_modules/@babel/traverse/lib/context.js:131:19)
          at traverseNode (node_modules/@babel/traverse/lib/traverse-node.js:24:17)
          at NodePath.visit (node_modules/@babel/traverse/lib/path/context.js:107:52)
          at TraversalContext.visitQueue (node_modules/@babel/traverse/lib/context.js:105:16)
          at TraversalContext.visitSingle (node_modules/@babel/traverse/lib/context.js:79:19)
          at TraversalContext.visit (node_modules/@babel/traverse/lib/context.js:133:19)
          at traverseNode (node_modules/@babel/traverse/lib/traverse-node.js:24:17)
          at traverse (node_modules/@babel/traverse/lib/index.js:62:34)
          at toBabel (node_modules/swc-to-babel/lib/swc-to-babel.js:52:5)
    

    I believe this is due to the const assertion (as const) being surrounded by parens. I don't get the error if I remove the parens:

    const foo = [1, 2] as const;
    

    Fixes #14

    opened by lencioni 3
  • TypeError: Property object of MemberExpression expected node to be of a type [

    TypeError: Property object of MemberExpression expected node to be of a type ["Expression","Super"] but instead got "TsConstAssertion"

    When parsing the following ts code with swc (options are { syntax: 'typescript' }) and then passing the result to swc-to-babel:

    const foo = ([1, 2] as const);
    

    I get the following error:

    TypeError: Property object of MemberExpression expected node to be of a type ["Expression","Super"] but instead got "TsConstAssertion"
    

    Here's the relevant part of the stack trace:

          at Object.validate (node_modules/@babel/types/src/definitions/utils.ts:138:11)
          at validate (node_modules/@babel/types/src/validators/validate.ts:32:9)
          at validateField (node_modules/@babel/types/src/validators/validate.ts:19:3)
          at NodePath._replaceWith (node_modules/@babel/traverse/lib/path/replacement.js:169:5)
          at NodePath.replaceWith (node_modules/@babel/traverse/lib/path/replacement.js:151:8)
          at Object.<anonymous>.module.exports.convertParenthesisExpression (node_modules/swc-to-babel/lib/swc/index.js:132:10)
          at enter (node_modules/swc-to-babel/lib/swc-to-babel.js:119:24)
          at NodePath._call (node_modules/@babel/traverse/lib/path/context.js:53:20)
          at NodePath.call (node_modules/@babel/traverse/lib/path/context.js:36:14)
          at NodePath.visit (node_modules/@babel/traverse/lib/path/context.js:100:31)
          at TraversalContext.visitQueue (node_modules/@babel/traverse/lib/context.js:105:16)
          at TraversalContext.visitSingle (node_modules/@babel/traverse/lib/context.js:79:19)
          at TraversalContext.visit (node_modules/@babel/traverse/lib/context.js:133:19)
          at traverseNode (node_modules/@babel/traverse/lib/traverse-node.js:24:17)
          at NodePath.visit (node_modules/@babel/traverse/lib/path/context.js:107:52)
          at TraversalContext.visitQueue (node_modules/@babel/traverse/lib/context.js:105:16)
          at TraversalContext.visitSingle (node_modules/@babel/traverse/lib/context.js:79:19)
          at TraversalContext.visit (node_modules/@babel/traverse/lib/context.js:133:19)
          at traverseNode (node_modules/@babel/traverse/lib/traverse-node.js:24:17)
          at NodePath.visit (node_modules/@babel/traverse/lib/path/context.js:107:52)
          at TraversalContext.visitQueue (node_modules/@babel/traverse/lib/context.js:105:16)
          at TraversalContext.visitSingle (node_modules/@babel/traverse/lib/context.js:79:19)
          at TraversalContext.visit (node_modules/@babel/traverse/lib/context.js:133:19)
          at traverseNode (node_modules/@babel/traverse/lib/traverse-node.js:24:17)
          at NodePath.visit (node_modules/@babel/traverse/lib/path/context.js:107:52)
          at TraversalContext.visitQueue (node_modules/@babel/traverse/lib/context.js:105:16)
          at TraversalContext.visitMultiple (node_modules/@babel/traverse/lib/context.js:74:17)
          at TraversalContext.visit (node_modules/@babel/traverse/lib/context.js:131:19)
          at traverseNode (node_modules/@babel/traverse/lib/traverse-node.js:24:17)
          at NodePath.visit (node_modules/@babel/traverse/lib/path/context.js:107:52)
          at TraversalContext.visitQueue (node_modules/@babel/traverse/lib/context.js:105:16)
          at TraversalContext.visitQueue (node_modules/@babel/traverse/lib/context.js:111:21)
          at TraversalContext.visitSingle (node_modules/@babel/traverse/lib/context.js:79:19)
          at TraversalContext.visit (node_modules/@babel/traverse/lib/context.js:133:19)
          at traverseNode (node_modules/@babel/traverse/lib/traverse-node.js:24:17)
          at NodePath.visit (node_modules/@babel/traverse/lib/path/context.js:107:52)
          at TraversalContext.visitQueue (node_modules/@babel/traverse/lib/context.js:105:16)
          at TraversalContext.visitMultiple (node_modules/@babel/traverse/lib/context.js:74:17)
          at TraversalContext.visit (node_modules/@babel/traverse/lib/context.js:131:19)
          at traverseNode (node_modules/@babel/traverse/lib/traverse-node.js:24:17)
          at NodePath.visit (node_modules/@babel/traverse/lib/path/context.js:107:52)
          at TraversalContext.visitQueue (node_modules/@babel/traverse/lib/context.js:105:16)
          at TraversalContext.visitSingle (node_modules/@babel/traverse/lib/context.js:79:19)
          at TraversalContext.visit (node_modules/@babel/traverse/lib/context.js:133:19)
          at traverseNode (node_modules/@babel/traverse/lib/traverse-node.js:24:17)
          at NodePath.visit (node_modules/@babel/traverse/lib/path/context.js:107:52)
          at TraversalContext.visitQueue (node_modules/@babel/traverse/lib/context.js:105:16)
          at TraversalContext.visitMultiple (node_modules/@babel/traverse/lib/context.js:74:17)
          at TraversalContext.visit (node_modules/@babel/traverse/lib/context.js:131:19)
          at traverseNode (node_modules/@babel/traverse/lib/traverse-node.js:24:17)
          at NodePath.visit (node_modules/@babel/traverse/lib/path/context.js:107:52)
          at TraversalContext.visitQueue (node_modules/@babel/traverse/lib/context.js:105:16)
          at TraversalContext.visitSingle (node_modules/@babel/traverse/lib/context.js:79:19)
          at TraversalContext.visit (node_modules/@babel/traverse/lib/context.js:133:19)
          at traverseNode (node_modules/@babel/traverse/lib/traverse-node.js:24:17)
          at traverse (node_modules/@babel/traverse/lib/index.js:62:34)
          at toBabel (node_modules/swc-to-babel/lib/swc-to-babel.js:52:5)
    

    I believe this is due to the const assertion (as const) being surrounded by parens. I don't get the error if I remove the parens:

    const foo = [1, 2] as const;
    
    opened by lencioni 3
  • KeyValueProperty doesn't get properly converted to the babel equivelant

    KeyValueProperty doesn't get properly converted to the babel equivelant

    Reproduction

    Code:

    Object.defineProperty(exports, "__esModule", {
      value: true
    });
    
    swc ast:
    {
      "type": "Module",
      "span": {
        "start": 0,
        "end": 64,
        "ctxt": 0
      },
      "body": [
        {
          "type": "ExpressionStatement",
          "span": {
            "start": 0,
            "end": 64,
            "ctxt": 0
          },
          "expression": {
            "type": "CallExpression",
            "span": {
              "start": 0,
              "end": 63,
              "ctxt": 0
            },
            "callee": {
              "type": "MemberExpression",
              "span": {
                "start": 0,
                "end": 21,
                "ctxt": 0
              },
              "object": {
                "type": "Identifier",
                "span": {
                  "start": 0,
                  "end": 6,
                  "ctxt": 0
                },
                "value": "Object",
                "optional": false
              },
              "property": {
                "type": "Identifier",
                "span": {
                  "start": 7,
                  "end": 21,
                  "ctxt": 0
                },
                "value": "defineProperty",
                "optional": false
              }
            },
            "arguments": [
              {
                "spread": null,
                "expression": {
                  "type": "Identifier",
                  "span": {
                    "start": 22,
                    "end": 29,
                    "ctxt": 0
                  },
                  "value": "exports",
                  "optional": false
                }
              },
              {
                "spread": null,
                "expression": {
                  "type": "StringLiteral",
                  "span": {
                    "start": 31,
                    "end": 43,
                    "ctxt": 0
                  },
                  "value": "__esModule",
                  "raw": "\"__esModule\""
                }
              },
              {
                "spread": null,
                "expression": {
                  "type": "ObjectExpression",
                  "span": {
                    "start": 45,
                    "end": 62,
                    "ctxt": 0
                  },
                  "properties": [
                    {
                      "type": "KeyValueProperty",
                      "key": {
                        "type": "Identifier",
                        "span": {
                          "start": 49,
                          "end": 54,
                          "ctxt": 0
                        },
                        "value": "value",
                        "optional": false
                      },
                      "value": {
                        "type": "BooleanLiteral",
                        "span": {
                          "start": 56,
                          "end": 60,
                          "ctxt": 0
                        },
                        "value": true
                      }
                    }
                  ]
                }
              }
            ],
            "typeArguments": null
          }
        }
      ],
      "interpreter": null
    }
    
    Output babel AST
    {
        "type": "File",
        "program": {
            "type": "Program",
            "body": [
                {
                    "type": "ExpressionStatement",
                    "expression": {
                        "type": "CallExpression",
                        "callee": {
                            "type": "MemberExpression",
                            "object": {
                                "type": "Identifier",
                                "name": "Object"
                            },
                            "property": {
                                "type": "Identifier",
                                "name": "defineProperty"
                            },
                            "computed": false
                        },
                        "arguments": [
                            {
                                "type": "Identifier",
                                "name": "exports"
                            },
                            {
                                "type": "StringLiteral",
                                "value": "__esModule",
                                "raw": "\"__esModule\"",
                                "extra": {
                                    "raw": "\"__esModule\""
                                }
                            },
                            {
                                "type": "ObjectExpression",
                                "properties": [
                                    {
                                        "type": "KeyValueProperty",
                                        "key": {
                                            "type": "Identifier",
                                            "span": {
                                                "start": 49,
                                                "end": 54,
                                                "ctxt": 0
                                            },
                                            "value": "value",
                                            "optional": false
                                        },
                                        "value": {
                                            "type": "BooleanLiteral",
                                            "span": {
                                                "start": 56,
                                                "end": 60,
                                                "ctxt": 0
                                            },
                                            "value": true
                                        }
                                    }
                                ]
                            }
                        ]
                    }
                }
            ],
            "interpreter": null,
            "directives": [],
            "sourceType": "module"
        },
        "comments": []
    }
    
    Expected AST
    {
      "type": "File",
      "start": 0,
      "end": 65,
      "loc": {
        "start": {
          "line": 1,
          "column": 0,
          "index": 0
        },
        "end": {
          "line": 4,
          "column": 0,
          "index": 65
        }
      },
      "errors": [],
      "program": {
        "type": "Program",
        "start": 0,
        "end": 65,
        "loc": {
          "start": {
            "line": 1,
            "column": 0,
            "index": 0
          },
          "end": {
            "line": 4,
            "column": 0,
            "index": 65
          }
        },
        "sourceType": "module",
        "interpreter": null,
        "body": [
          {
            "type": "ExpressionStatement",
            "start": 0,
            "end": 64,
            "loc": {
              "start": {
                "line": 1,
                "column": 0,
                "index": 0
              },
              "end": {
                "line": 3,
                "column": 3,
                "index": 64
              }
            },
            "expression": {
              "type": "CallExpression",
              "start": 0,
              "end": 63,
              "loc": {
                "start": {
                  "line": 1,
                  "column": 0,
                  "index": 0
                },
                "end": {
                  "line": 3,
                  "column": 2,
                  "index": 63
                }
              },
              "callee": {
                "type": "MemberExpression",
                "start": 0,
                "end": 21,
                "loc": {
                  "start": {
                    "line": 1,
                    "column": 0,
                    "index": 0
                  },
                  "end": {
                    "line": 1,
                    "column": 21,
                    "index": 21
                  }
                },
                "object": {
                  "type": "Identifier",
                  "start": 0,
                  "end": 6,
                  "loc": {
                    "start": {
                      "line": 1,
                      "column": 0,
                      "index": 0
                    },
                    "end": {
                      "line": 1,
                      "column": 6,
                      "index": 6
                    },
                    "identifierName": "Object"
                  },
                  "name": "Object"
                },
                "computed": false,
                "property": {
                  "type": "Identifier",
                  "start": 7,
                  "end": 21,
                  "loc": {
                    "start": {
                      "line": 1,
                      "column": 7,
                      "index": 7
                    },
                    "end": {
                      "line": 1,
                      "column": 21,
                      "index": 21
                    },
                    "identifierName": "defineProperty"
                  },
                  "name": "defineProperty"
                }
              },
              "arguments": [
                {
                  "type": "Identifier",
                  "start": 22,
                  "end": 29,
                  "loc": {
                    "start": {
                      "line": 1,
                      "column": 22,
                      "index": 22
                    },
                    "end": {
                      "line": 1,
                      "column": 29,
                      "index": 29
                    },
                    "identifierName": "exports"
                  },
                  "name": "exports"
                },
                {
                  "type": "StringLiteral",
                  "start": 31,
                  "end": 43,
                  "loc": {
                    "start": {
                      "line": 1,
                      "column": 31,
                      "index": 31
                    },
                    "end": {
                      "line": 1,
                      "column": 43,
                      "index": 43
                    }
                  },
                  "extra": {
                    "rawValue": "__esModule",
                    "raw": "\"__esModule\""
                  },
                  "value": "__esModule"
                },
                {
                  "type": "ObjectExpression",
                  "start": 45,
                  "end": 62,
                  "loc": {
                    "start": {
                      "line": 1,
                      "column": 45,
                      "index": 45
                    },
                    "end": {
                      "line": 3,
                      "column": 1,
                      "index": 62
                    }
                  },
                  "properties": [
                    {
                      "type": "ObjectProperty",
                      "start": 49,
                      "end": 60,
                      "loc": {
                        "start": {
                          "line": 2,
                          "column": 2,
                          "index": 49
                        },
                        "end": {
                          "line": 2,
                          "column": 13,
                          "index": 60
                        }
                      },
                      "method": false,
                      "key": {
                        "type": "Identifier",
                        "start": 49,
                        "end": 54,
                        "loc": {
                          "start": {
                            "line": 2,
                            "column": 2,
                            "index": 49
                          },
                          "end": {
                            "line": 2,
                            "column": 7,
                            "index": 54
                          },
                          "identifierName": "value"
                        },
                        "name": "value"
                      },
                      "computed": false,
                      "shorthand": false,
                      "value": {
                        "type": "BooleanLiteral",
                        "start": 56,
                        "end": 60,
                        "loc": {
                          "start": {
                            "line": 2,
                            "column": 9,
                            "index": 56
                          },
                          "end": {
                            "line": 2,
                            "column": 13,
                            "index": 60
                          }
                        },
                        "value": true
                      }
                    }
                  ]
                }
              ]
            }
          }
        ],
        "directives": []
      },
      "comments": []
    }
    

    Expected behaviour

    KeyValueProperty nodes should be replaced with the proper ObjectProperty node equivelant

    Current behaviour

    KeyValueProperty nodes aren't replaced at all producing an invalid ast

    feature 
    opened by Markos-Th09 3
Releases(v1.26.0)
Owner
coderaiser
coderaiser
Babel-plugin-amd-checker - Module format checking plugin for Babel usable in both Node.js the web browser environments.

babel-plugin-amd-checker A Babel plugin to check the format of your modules when compiling your code using Babel. This plugin allows you to abort the

Ferdinand Prantl 1 Jan 6, 2022
Babel plugin and helper functions for interoperation between Node.js native ESM and Babel ESM

babel-plugin-node-cjs-interop and node-cjs-interop: fix the default import interoperability issue in Node.js The problem to solve Consider the followi

Masaki Hara 15 Nov 6, 2022
Manipulate the AST to transform your code.

unplugin-ast Manipulate the AST to transform your code. Installation npm i unplugin-ast Vite // vite.config.ts import AST from 'unplugin-ast/vite' ex

ไธ‰ๅ’ฒๆ™บๅญ 32 Dec 3, 2022
SWC plugin for transforming import path.

swc-plugin-transform-import Inspired from babel-plugin-transform-imports Installation npm i -D swc-plugin-transform-import Uses with webpack-config //

Ankit Chouhan 35 Dec 24, 2022
Storybook add-on to enable SWC builds.

storybook-addon-swc Storybook addon that improves build time by building with swc. ?? Examples webpack4 webpack5 ?? Installation $ npm install -D stor

Karibash 49 Dec 20, 2022
๐Ÿ’…โ€A ready-to-go with a well-thought-out structure Electron app boilerplate with ReactJS, TypeScript, CSS / SASS modules, SWC, Eslint, Prettier, GitHub Action releases and more.

Electron App ?? โ€A ready-to-go with a well-thought-out structure Electron app boilerplate with ReactJS, TypeScript, CSS / SASS modules, SWC, Eslint, P

Dalton Menezes 155 Dec 29, 2022
An experimental transpiler to bring tailwind macros to SWC ๐Ÿš€

stailwc (speedy tailwind compiler) This is an experimental SWC transpiler to bring compile time tailwind macros to SWC (and nextjs) a-la twin macro. T

Alexander Lyon 140 Jan 3, 2023
Rollup + Babel + Prettier + Strict ESlint + VSCode - Enterprise grade boilerplate

Javascript package boilerplate by HackingBay Rollup + Babel + Prettier + Strict ESlint + VSCode - Enterprise grade boilerplate Minimalist js package b

HackingBay 1 Dec 28, 2021
Rollup + React + Babel + Prettier + Strict ESlint and Stylelint + Sass + VSCode + Playground app - Enterprise grade boilerplate

React package boilerplate by HackingBay Rollup + React 17 + Babel + Prettier + Strict ESlint and Stylelint + Sass + VSCode + Playground app - Enterpri

HackingBay 2 Jan 19, 2022
babel-plugin

babel ๆ’ไปถ้›†ๅˆ ๆ‰€ๆœ‰ๆ’ไปถ ่กŒ่ฆ†็›–็Ž‡ใ€ๅ‡ฝๆ•ฐ่ฆ†็›–็Ž‡ใ€ๅˆ†ๆ”ฏ่ฆ†็›–็Ž‡ใ€่ฏญๅฅ่ฆ†็›–็Ž‡ๅฑ…ๅ‡่พพๅˆฐ100% ้กน็›ฎ ไป‹็ป ไฝฟ็”จ License npm i babel-plugin-remove-console-retain ็งป้™ค้กน็›ฎไธญ็š„ conosle, ๅŒๆ—ถๅฏไปฅ้€‰ๆ‹ฉไฟ็•™ไธ€ไบ› conosle npm i babe

null 11 Nov 9, 2022
Kakapo for Desktop, Web, iOS, Android, Babel, Reflux, ImmutableJs, HowlerJs, Webpack

Kakapo is an open source ambient sound mixer for relaxation or productivity, available on the Chrome Web Store. See also: Kakapo for Desktop & Web - K

Dredsoft 3 Sep 15, 2022
Yunisdev-table2csv - Lightweight library to convert HTML table to CSV file

Installation Add following HTML before body end: <script src="https://yunisdev.github.io/table2csv/table2csv.min.js"></script> <!-- or --> <script src

Yunis Huseynzade 2 Oct 19, 2020
Convert JSON to human readable HTML

json.human.js: Json Formatting for Human Beings A small library to convert a JSON object into a human readable HTML representation that is easy to sty

Mariano Guerra 955 Dec 3, 2022
convert markdown to html in under 5kb

convert markdown to HTML in under 5kb take a look at the to PHP translated version: https://github.com/SimonWaldherr/micromarkdown.php about License:

Simon Waldherr 201 Dec 8, 2022
Mercury: easily convert Python notebook to web app and share with others

Mercury Share your Python notebooks with others Easily convert your Python notebooks into interactive web apps by adding parameters in YAML. Simply ad

MLJAR 2.2k Dec 30, 2022
Convert and Calculate by RPN for typescript.

Coaca.ts: Convert and Calculate by RPN for typescript ๆณจๆ„็‚น ใพใšใใ‚‚ใใ‚‚ใ€typescriptใฏใ‚ตใƒผใƒใ‚ตใ‚คใƒ‰ใงไฝฟ็”จใ•ใ‚Œใ‚‹ในใ่จ€่ชžใงใ™ใ€‚ไธ€ๅฟœtypescript4.5ไปฅ้™ใฎๆฉŸ่ƒฝใ‚’็”จใ„ใฆใ„ใพใ™ใŒใ€typescriptใฎๆœฌๆฅใฎไฝฟใ„ๆ–นใ‚’่ถ…่ถŠใ—ใฆใพใ™ใ€‚ใ”

่ตค็ดซ 2 Aug 24, 2022
MZ-Switchwire - Convert Anycubic Mega Zero v1 to Switchwire

Anycubic Mega Zero v1 Switchwire Mod 390mm X-Axis with MGN9H - Click for 3D prev

null 5 Dec 25, 2022
A command-line tool to convert Project Zomboid map data into Deep Zoom format

pzmap2dzi pzmap2dzi is a command-line tool running on Windows to convert Project Zomboid map data into Deep Zoom format. Features Supports both python

Min Xiang 14 Dec 31, 2022
Convert some JavaScript/TypeScript code string into a .d.ts TypeScript Declaration code string

convert-to-dts Converts the source code for any .js or .ts file into the equivalent .d.ts code TypeScript would generate. Usage import { convertToDecl

Lily Scott 11 Mar 3, 2022