Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

inputSourceMap option has a bug #4578

Closed
lewisl9029 opened this issue May 9, 2022 · 8 comments · Fixed by #6561
Closed

inputSourceMap option has a bug #4578

lewisl9029 opened this issue May 9, 2022 · 8 comments · Fixed by #6561
Assignees
Labels
Milestone

Comments

@lewisl9029
Copy link
Contributor

Describe the bug

In types.ts, I see the following docs and type defs for inputSourceMap:

  /**
   * `true` will attempt to load an input sourcemap from the file itself, if it
   * contains a //# sourceMappingURL=... comment. If no map is found, or the
   * map fails to load and parse, it will be silently discarded.
   *
   *  If an object is provided, it will be treated as the source map object itself.
   *
   * Defaults to `true`.
   */
  inputSourceMap?: boolean | string;

The description says that we should be able to pass in the sourcemap as an object, but the types only specify boolean and string, and when I actually try to pass in an object, I get the following error:

Error: Failed to deserialize buffer as swc::config::Options
JSON: {"inputSourceMap":{"version":3,"names":["test"],"sources":["unknown"],"sourcesContent":["export const test = \"1234\""],"mappings":"AAAA,OAAO,MAAMA,IAAI,GAAG,MAAb"}}

Caused by:
    data did not match any variant of untagged enum InputSourceMap at line 1 column 165
    at Compiler.transformSync (/home/runner/O9ukU1Lkv00/node_modules/@swc/core/index.js:137:25)
    at Object.transformSync (/home/runner/O9ukU1Lkv00/node_modules/@swc/core/index.js:217:21)
    at Object.<anonymous> (/home/runner/O9ukU1Lkv00/index.js:10:21)
    at Module._compile (node:internal/modules/cjs/loader:1103:14)

Couldn't see a way to repro this in the playground, so I made a quick repro at replit instead, let me know if there's a preferred alternative: https://replit.com/@lewisl9029/swc-inputSourceMap-repro

Curious if this is a bug or was it never supported in the first place? If it's the latter, please consider this a feature request! I have a use case where I'm using swc as a fast minifier for a babel transformed file (I have a lot of custom babel plugins that still need to be rewritten using the new WASM plugin system before I can replace babel completely), and would like to preserve source mapping functionality if possible. Thanks!

Input code

const swc_ = require('@swc/core')
const babel_ = require('@babel/core')

const {code, map} = 
  babel_.transformSync('export const test = "1234"', { 
    sourceMaps: true 
  })
console.log({ code, map})

const result = swc_.transformSync(code, { inputSourceMap: map })
console.log(result)

Config

No response

Playground link

https://replit.com/@lewisl9029/swc-inputSourceMap-repro

Expected behavior

SWC uses supplied sourcemap object

Actual behavior

SWC crashes with the following output:

{
  code: 'export const test = "1234";',
  map: {
    version: 3,
    file: undefined,
    names: [ 'test' ],
    sourceRoot: undefined,
    sources: [ 'unknown' ],
    sourcesContent: [ 'export const test = "1234"' ],
    mappings: 'AAAA,OAAO,MAAMA,IAAI,GAAG,MAAb'
  }
}
Error: Failed to deserialize buffer as swc::config::Options
JSON: {"inputSourceMap":{"version":3,"names":["test"],"sources":["unknown"],"sourcesContent":["export const test = \"1234\""],"mappings":"AAAA,OAAO,MAAMA,IAAI,GAAG,MAAb"}}

Caused by:
    data did not match any variant of untagged enum InputSourceMap at line 1 column 165
    at Compiler.transformSync (/home/runner/O9ukU1Lkv00/node_modules/@swc/core/index.js:137:25)
    at Object.transformSync (/home/runner/O9ukU1Lkv00/node_modules/@swc/core/index.js:217:21)
    at Object.<anonymous> (/home/runner/O9ukU1Lkv00/index.js:10:21)
    at Module._compile (node:internal/modules/cjs/loader:1103:14)

Version

1.2.179

Additional context

No response

@kdy1
Copy link
Member

kdy1 commented May 9, 2022

This is because I copied the description from babel.
This is not a bug

@kdy1 kdy1 closed this as completed May 9, 2022
@lewisl9029
Copy link
Contributor Author

Ah understood. Is there some other way to pass through a sourcemap that only exists in-memory?

@kdy1
Copy link
Member

kdy1 commented May 9, 2022

You can stringify it

@lewisl9029
Copy link
Contributor Author

Ah nice! I just gave that a try, and it no longer throws, but the source locations seem to be off.

I updated the replit with the simplest repro I could think of: https://replit.com/@lewisl9029/swc-inputSourceMap-repro

npm run test2 will run the script from babel before minification, and npm run test will run the script after minified by swc.

test2's stacktrace points to the original source location where the error is thrown, but test's stacktrace seems to be pointing at a completely unrelated location towards the end of the script.

@lewisl9029
Copy link
Contributor Author

lewisl9029 commented May 9, 2022

Extracting all the necessary info here for convenience:

This is index.js, the module used to generate the test files:

const swc_ = require('@swc/core')
const babel_ = require('@babel/core')
const fs_ = require('fs')

const { code, map } =
  babel_.transformSync(fs_.readFileSync('./input.js'), {
    sourceMaps: true
  })
console.log({ code, map })

const result = swc_.transformSync(code, {
  inputSourceMap: JSON.stringify(map), 
  sourceMaps: 'inline',
  jsc: {
    minify: {
      compress: true,
      mangle: true,
    },
  },
  minify: true,
})

fs_.writeFileSync('./test.js', result.code)


const result2 =
  babel_.transformSync(fs_.readFileSync('./input.js'), {
    sourceMaps: 'inline'
  })

fs_.writeFileSync('./test2.js', result2.code)

This is input.js, the file used as input to babel:

const test = "1234"

/* this should throw on line 3 */ throw new Error('hi')

const test2 = 1

This is test.js, the output of babel then minified by swc:

throw new Error("hi")
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInVua25vd24iLCI8YW5vbj4iXSwic291cmNlc0NvbnRlbnQiOlsiY29uc3QgdGVzdCA9IFwiMTIzNFwiXG5cbi8qIHRoaXMgc2hvdWxkIHRocm93IG9uIGxpbmUgMyAqLyB0aHJvdyBuZXcgRXJyb3IoJ2hpJylcblxuY29uc3QgdGVzdDIgPSAxIiwiY29uc3QgdGVzdCA9IFwiMTIzNFwiO1xuLyogdGhpcyBzaG91bGQgdGhyb3cgb24gbGluZSAzICovXG5cbnRocm93IG5ldyBFcnJvcignaGknKTtcbmNvbnN0IHRlc3QyID0gMTsiXSwibmFtZXMiOlsiRXJyb3IiXSwibWFwcGluZ3MiOiJBQUlBLE1BQU0sSUFBQUEsS0FBTixDQUFBLElBQUEsQ0FBQSJ9

This is test2.js, output of just babel:

const test = "1234";
/* this should throw on line 3 */

throw new Error('hi');
const test2 = 1;
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJ0ZXN0IiwiRXJyb3IiLCJ0ZXN0MiJdLCJzb3VyY2VzIjpbInVua25vd24iXSwic291cmNlc0NvbnRlbnQiOlsiY29uc3QgdGVzdCA9IFwiMTIzNFwiXG5cbi8qIHRoaXMgc2hvdWxkIHRocm93IG9uIGxpbmUgMyAqLyB0aHJvdyBuZXcgRXJyb3IoJ2hpJylcblxuY29uc3QgdGVzdDIgPSAxIl0sIm1hcHBpbmdzIjoiQUFBQSxNQUFNQSxJQUFJLEdBQUcsTUFBYjtBQUVBOztBQUFrQyxNQUFNLElBQUlDLEtBQUosQ0FBVSxJQUFWLENBQU47QUFFbEMsTUFBTUMsS0FBSyxHQUFHLENBQWQifQ==

Results of running test vs test2:

~/swc-inputSourceMap-repro$ npm run test

> swc-inputsourcemap-repro@1.0.0 test
> node --enable-source-maps test.js

Error: hi
    at Object.<anonymous> (/home/runner/swc-inputSourceMap-repro/unknown:5:7)
    at Module._compile (node:internal/modules/cjs/loader:1103:14)
    at Object.Module._extensions..js (node:internal/modules/cjs/loader:1157:10)
    at Module.load (node:internal/modules/cjs/loader:981:32)
    at Function.Module._load (node:internal/modules/cjs/loader:822:12)
    at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:77:12)
    at node:internal/main/run_main_module:17:47
~/swc-inputSourceMap-repro$ npm run test2

> swc-inputsourcemap-repro@1.0.0 test2
> node --enable-source-maps test2.js

Error: hi
    at Object.<anonymous> (/home/runner/swc-inputSourceMap-repro/unknown:3:41)
    at Module._compile (node:internal/modules/cjs/loader:1103:14)
    at Object.Module._extensions..js (node:internal/modules/cjs/loader:1157:10)
    at Module.load (node:internal/modules/cjs/loader:981:32)
    at Function.Module._load (node:internal/modules/cjs/loader:822:12)
    at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:77:12)
    at node:internal/main/run_main_module:17:47

@kdy1 kdy1 reopened this May 9, 2022
@kdy1 kdy1 changed the title swc.transform throws when passing in inputSourceMap as object inputSourceMap option has a bug May 9, 2022
@kdy1 kdy1 added this to the Planned milestone May 9, 2022
@kdy1 kdy1 modified the milestones: Planned, v1.2.199 Jun 11, 2022
@ChrisCindy
Copy link

Is this bug fixed ?

@elado
Copy link

elado commented Nov 10, 2022

@ChrisCindy - doesn't seem like, I am still experiencing it. Needed to do some work to drop Babel and use only SWC to have source maps correct.

@kdy1 kdy1 self-assigned this Dec 1, 2022
@kdy1 kdy1 closed this as completed in #6561 Dec 2, 2022
kdy1 added a commit that referenced this issue Dec 2, 2022
**Related issue:**

 - Closes #4578.
 - Closes #6244.
 - vercel/next.js#39878.

Co-authored-by: Justin Ridgewell <justin@ridgewell.name>
@kdy1 kdy1 modified the milestones: Planned, v1.3.22 Dec 9, 2022
@swc-bot
Copy link
Collaborator

swc-bot commented Jan 8, 2023

This closed issue has been automatically locked because it had no new activity for a month. If you are running into a similar issue, please create a new issue with the steps to reproduce. Thank you.

@swc-project swc-project locked as resolved and limited conversation to collaborators Jan 8, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Development

Successfully merging a pull request may close this issue.

5 participants