Skip to content

Commit 24f5e62

Browse files
committed
add IIFETranspiler
1 parent 576b99f commit 24f5e62

File tree

5 files changed

+42
-12
lines changed

5 files changed

+42
-12
lines changed

packages/cubejs-schema-compiler/src/compiler/DataSchemaCompiler.ts

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -688,18 +688,7 @@ export class DataSchemaCompiler {
688688
return this.compiledScriptCache.get(cacheKey)!;
689689
}
690690

691-
// As we run all data model files in the same context,
692-
// we need to wrap the code in an IIFE to avoid errors like:
693-
// Identifier 'xxx' has already been declared,
694-
// avoid polluting and modifying the global scope,
695-
// and to provide a controlled environment for the code execution.
696-
const wrappedCode = `
697-
(function() {
698-
${file.content}
699-
})();
700-
`;
701-
702-
const script = new vm.Script(wrappedCode, { filename: file.fileName });
691+
const script = new vm.Script(file.content, { filename: file.fileName });
703692
this.compiledScriptCache.set(cacheKey, script);
704693
return script;
705694
}

packages/cubejs-schema-compiler/src/compiler/PrepareCompiler.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { DataSchemaCompiler } from './DataSchemaCompiler';
99
import {
1010
CubeCheckDuplicatePropTranspiler,
1111
CubePropContextTranspiler,
12+
IIFETranspiler,
1213
ImportExportTranspiler,
1314
TranspilerInterface,
1415
ValidationTranspiler,
@@ -63,6 +64,7 @@ export const prepareCompiler = (repo: SchemaFileRepository, options: PrepareComp
6364
new ValidationTranspiler(),
6465
new ImportExportTranspiler(),
6566
new CubePropContextTranspiler(cubeSymbols, cubeDictionary, viewCompiler),
67+
new IIFETranspiler(),
6668
];
6769

6870
if (!options.allowJsDuplicatePropsInSchema) {
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import * as t from '@babel/types';
2+
import type { NodePath } from '@babel/traverse';
3+
import type { TranspilerInterface, TraverseObject } from './transpiler.interface';
4+
import type { ErrorReporter } from '../ErrorReporter';
5+
6+
/**
7+
* IIFETranspiler wraps the entire file content in an Immediately Invoked Function Expression (IIFE).
8+
* This prevents:
9+
* - Variable redeclaration errors when multiple files define the same variables
10+
* - Global scope pollution between data model files
11+
* - Provides isolated execution context for each file
12+
*/
13+
export class IIFETranspiler implements TranspilerInterface {
14+
public traverseObject(_reporter: ErrorReporter): TraverseObject {
15+
return {
16+
Program: (path: NodePath<t.Program>) => {
17+
const { body } = path.node;
18+
19+
if (body.length > 0) {
20+
// Create an IIFE that wraps all the existing statements
21+
const iife = t.callExpression(
22+
t.functionExpression(
23+
null, // anonymous function
24+
[],
25+
t.blockStatement(body)
26+
),
27+
[]
28+
);
29+
30+
// Replace the program body with the IIFE
31+
path.node.body = [t.expressionStatement(iife)];
32+
}
33+
}
34+
};
35+
}
36+
}

packages/cubejs-schema-compiler/src/compiler/transpilers/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,5 @@ export * from './ImportExportTranspiler';
22
export * from './CubePropContextTranspiler';
33
export * from './CubeCheckDuplicatePropTranspiler';
44
export * from './ValidationTranspiler';
5+
export * from './IIFETranspiler';
56
export * from './transpiler.interface';

packages/cubejs-schema-compiler/src/compiler/transpilers/transpiler_worker.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { CubePropContextTranspiler } from './CubePropContextTranspiler';
1010
import { ErrorReporter } from '../ErrorReporter';
1111
import { LightweightSymbolResolver } from './LightweightSymbolResolver';
1212
import { LightweightNodeCubeDictionary } from './LightweightNodeCubeDictionary';
13+
import { IIFETranspiler } from './IIFETranspiler';
1314

1415
type TransferContent = {
1516
fileName: string;
@@ -28,6 +29,7 @@ const transpilers = {
2829
ImportExportTranspiler: new ImportExportTranspiler(),
2930
CubeCheckDuplicatePropTranspiler: new CubeCheckDuplicatePropTranspiler(),
3031
CubePropContextTranspiler: new CubePropContextTranspiler(cubeSymbols, cubeDictionary, cubeSymbols),
32+
IIFETranspiler: new IIFETranspiler(),
3133
};
3234

3335
const transpile = (data: TransferContent) => {

0 commit comments

Comments
 (0)