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鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug]: Incorrect Documentation under @babel/generator #14132

Open
1 task
ForbiddenEra opened this issue Jan 11, 2022 · 3 comments
Open
1 task

[Bug]: Incorrect Documentation under @babel/generator #14132

ForbiddenEra opened this issue Jan 11, 2022 · 3 comments

Comments

@ForbiddenEra
Copy link

馃捇

  • Would you like to work on a fix?

How are you using Babel?

Programmatic API (babel.transform, babel.parse)

Input code

input - main.js

include('secondary.js')

console.log('I am Main');
let foo = new secondary();

input - secondary.js

class secondary {
    constructor() {
        console.log('I am secondary!');
    }
}

expected translated code output:

class secondary {
    constructor() {
        console.log('I am secondary!');
    }
}

console.log('I am Main');

My test code:

"use strict";
const util = require("util");
const fs = require("fs");
const babel = require("@babel/core");

compileJSX('ReactComponents.jsx');

function compileJSX(jsxfile) {
	let jsfile = jsxfile.replace('.jsx','.js');
	console.log(`JSX Cache Miss | Compiling scripts/jsx/${jsxfile} > cache/js/${jsfile}`);

	let rendered = null;

	let parserOpts = {
		preserveComments: true,
		attachComment: true, 	
		strictMode: true 		
	};

	let generatorOpts = {
		compact : false,
		minified: false,
		comment : false,
	};

	try {
		const t = require("@babel/types");

		let transformer = function(jsxFilename) {
			let jsxFile = fs.readFileSync(`${jsxFilename}`, `utf8`);
			let ret = babel.transformSync(jsxFile, {
				targets: `defaults`,
				ast: true,
				filenameRelative: `${jsxFilename}`,
				sourceType: `unambiguous`,
				sourceMaps: true,
				sourceFileName: `/js/${jsxFilename}`,
				sourceRoot: `/js/maps/`,
				highlightCode: true,
				presets: [
					[`@babel/preset-react`, {
							throwIfNamespace: true 
						}
					]
				],
				plugins: [
					{
						visitor: {
							CallExpression(path,state) {
								if (path.node.callee.name == 'include') {
									let included = transformer(path.node.arguments[0].value);
									let sourceMapComment = babel.template.ast(`null;//# sourceMappingURL=/js/maps/${path.node.arguments[0].value}`,
										{	preserveComments: true,
											comments: true
										});

									included.ast.program.body.push(sourceMapComment);
									path.replaceWithMultiple(included.ast.program.body);
								}
							}						}
					}
				],
				parserOpts,
				generatorOpts
			});

			fs.writeFileSync(`${jsxFilename}.map`, util.inspect(ret.map), `utf8`);

			return ret;
		}

		let parsed = transformer(jsxfile);

		console.log("code:")
		console.log(parsed);
	} catch (e) {
		console.log(util.inspect(e)); 

	return rendered;
}

Configuration file name

No response

Configuration

No response

Current and expected behavior

At https://babeljs.io/docs/en/babel-generator#ast-from-multiple-sources,

It shows the following example:

AST from Multiple Sources
In most cases, Babel does a 1:1 transformation of input-file to output-file. However, you may be dealing with AST constructed from multiple sources - JS files, templates, etc. If this is the case, and you want the sourcemaps to reflect the correct sources, you'll need to pass an object to generate as the code parameter. Keys should be the source filenames, and values should be the source content.

Here's an example of what that might look like:

import { parse } from "@babel/parser";
import generate from "@babel/generator";

const a = "var a = 1;";
const b = "var b = 2;";
const astA = parse(a, { sourceFilename: "a.js" });
const astB = parse(b, { sourceFilename: "b.js" });
const ast = {
  type: "Program",
  body: [].concat(astA.program.body, astB.program.body),
};

const { code, map } = generate(
  ast,
  { sourceMaps: true },
  {
    "a.js": a,
    "b.js": b,
  }
);

// Sourcemap will point to both a.js and b.js where appropriate.

I am unable to get this example working. I've tried modifying the code in a few ways that seem appropriate with no luck.

A few docs pages show the options having sourceFilename and other docs pages show it having sourceFileName.

https://babeljs.io/docs/en/babel-parser shows sourceFilename
https://babeljs.io/docs/en/babel-generator shows sourceFileName
https://babeljs.io/docs/en/options shows sourceFileName

Even if these were supposed to refer to different options, it feels odd that the casing is different and it's confusing and not consistent; in reality, parse won't accept sourceFilename anyway.

I'm creating a Babel plugin that will replace a include('filename') with the contents of that file, eg:

Environment

babel 7.16.7^
node 17.2.0^

Possible solution

No response

Additional context

No response

@babel-bot
Copy link
Collaborator

Hey @ForbiddenEra! We really appreciate you taking the time to report an issue. The collaborators on this project attempt to help as many people as possible, but we're a limited number of volunteers, so it's possible this won't be addressed swiftly.

If you need any help, or just have general Babel or JavaScript questions, we have a vibrant Slack community that typically always has someone willing to help. You can sign-up here for an invite.

@jridgewell
Copy link
Member

With #14246 and #14247, this sample code should work correctly.

@ForbiddenEra
Copy link
Author

With #14246 and #14247, this sample code should work correctly.

Awesome; I don't know if I'll have a chance to test my case anytime soon but if the sample code works then that's great!

I think the docs still might need to be updated; so with that and the fact I haven't tested I won't close this just yet; but if maintainers feel it's solved than feel free of course.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants