diff --git a/compiler/packages/babel-plugin-react-compiler/src/Entrypoint/Imports.ts b/compiler/packages/babel-plugin-react-compiler/src/Entrypoint/Imports.ts index c4f665720b4..6fc702fbf4c 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/Entrypoint/Imports.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/Entrypoint/Imports.ts @@ -240,7 +240,7 @@ export function addImportsToProgram( programContext: ProgramContext, ): void { const existingImports = getExistingImports(path); - const stmts: Array = []; + const stmts: Array = []; const sortedModules = [...programContext.imports.entries()].sort(([a], [b]) => a.localeCompare(b), ); @@ -303,9 +303,29 @@ export function addImportsToProgram( if (maybeExistingImports != null) { maybeExistingImports.pushContainer('specifiers', importSpecifiers); } else { - stmts.push( - t.importDeclaration(importSpecifiers, t.stringLiteral(moduleName)), - ); + if (path.node.sourceType === 'module') { + stmts.push( + t.importDeclaration(importSpecifiers, t.stringLiteral(moduleName)), + ); + } else { + stmts.push( + t.variableDeclaration('const', [ + t.variableDeclarator( + t.objectPattern( + sortedImport.map(specifier => { + return t.objectProperty( + t.identifier(specifier.imported), + t.identifier(specifier.name), + ); + }), + ), + t.callExpression(t.identifier('require'), [ + t.stringLiteral(moduleName), + ]), + ), + ]), + ); + } } } path.unshiftContainer('body', stmts); diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/script-source-type.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/script-source-type.expect.md new file mode 100644 index 00000000000..891a0fb0dde --- /dev/null +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/script-source-type.expect.md @@ -0,0 +1,52 @@ + +## Input + +```javascript +// @script +const React = require('react'); + +function Component(props) { + return
{props.name}
; +} + +// To work with snap evaluator +exports = { + FIXTURE_ENTRYPOINT: { + fn: Component, + params: [{name: 'React Compiler'}], + }, +}; + +``` + +## Code + +```javascript +const { c: _c } = require("react/compiler-runtime"); // @script +const React = require("react"); + +function Component(props) { + const $ = _c(2); + let t0; + if ($[0] !== props.name) { + t0 =
{props.name}
; + $[0] = props.name; + $[1] = t0; + } else { + t0 = $[1]; + } + return t0; +} + +// To work with snap evaluator +exports = { + FIXTURE_ENTRYPOINT: { + fn: Component, + params: [{ name: "React Compiler" }], + }, +}; + +``` + +### Eval output +(kind: ok)
React Compiler
\ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/script-source-type.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/script-source-type.js new file mode 100644 index 00000000000..604f0d96187 --- /dev/null +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/script-source-type.js @@ -0,0 +1,14 @@ +// @script +const React = require('react'); + +function Component(props) { + return
{props.name}
; +} + +// To work with snap evaluator +exports = { + FIXTURE_ENTRYPOINT: { + fn: Component, + params: [{name: 'React Compiler'}], + }, +}; diff --git a/compiler/packages/snap/src/compiler.ts b/compiler/packages/snap/src/compiler.ts index a6041bd5cc2..cafe8692446 100644 --- a/compiler/packages/snap/src/compiler.ts +++ b/compiler/packages/snap/src/compiler.ts @@ -31,10 +31,15 @@ import prettier from 'prettier'; import SproutTodoFilter from './SproutTodoFilter'; import {isExpectError} from './fixture-utils'; import {makeSharedRuntimeTypeProvider} from './sprout/shared-runtime-type-provider'; + export function parseLanguage(source: string): 'flow' | 'typescript' { return source.indexOf('@flow') !== -1 ? 'flow' : 'typescript'; } +export function parseSourceType(source: string): 'script' | 'module' { + return source.indexOf('@script') !== -1 ? 'script' : 'module'; +} + /** * Parse react compiler plugin + environment options from test fixture. Note * that although this primarily uses `Environment:parseConfigPragma`, it also @@ -98,6 +103,7 @@ export function parseInput( input: string, filename: string, language: 'flow' | 'typescript', + sourceType: 'module' | 'script', ): BabelCore.types.File { // Extract the first line to quickly check for custom test directives if (language === 'flow') { @@ -105,14 +111,14 @@ export function parseInput( babel: true, flow: 'all', sourceFilename: filename, - sourceType: 'module', + sourceType, enableExperimentalComponentSyntax: true, }); } else { return BabelParser.parse(input, { sourceFilename: filename, plugins: ['typescript', 'jsx'], - sourceType: 'module', + sourceType, }); } } @@ -221,11 +227,12 @@ export async function transformFixtureInput( const firstLine = input.substring(0, input.indexOf('\n')); const language = parseLanguage(firstLine); + const sourceType = parseSourceType(firstLine); // Preserve file extension as it determines typescript's babel transform // mode (e.g. stripping types, parsing rules for brackets) const filename = path.basename(fixturePath) + (language === 'typescript' ? '.ts' : ''); - const inputAst = parseInput(input, filename, language); + const inputAst = parseInput(input, filename, language, sourceType); // Give babel transforms an absolute path as relative paths get prefixed // with `cwd`, which is different across machines const virtualFilepath = '/' + filename; diff --git a/compiler/packages/snap/src/sprout/evaluator.ts b/compiler/packages/snap/src/sprout/evaluator.ts index 60da5dc53ce..8af8487d011 100644 --- a/compiler/packages/snap/src/sprout/evaluator.ts +++ b/compiler/packages/snap/src/sprout/evaluator.ts @@ -298,7 +298,10 @@ export function doEval(source: string): EvaluatorResult { return { kind: 'UnexpectedError', value: - 'Unexpected error during eval, possible syntax error?\n' + e.message, + 'Unexpected error during eval, possible syntax error?\n' + + e.message + + '\n\nsource:\n' + + source, logs, }; } finally {