jiti
jiti copied to clipboard
Cannot access 'xxx' before initialization
It feels like jiti do not support TS grammar like this : export declare class xxx
DEMO:
// entry.ts
export namespace smart_player_namespace {
export declare class FeedService {}
}
export type FeedService = smart_player_namespace.FeedService;
export const FeedService = smart_player_namespace.FeedService;
The place use jiti:
const createJITI = require('jiti');
const jiti = createJITI();
const content = jiti('./entry.ts');
console.log(content);
Then you can find an error:
ReferenceError: Cannot access 'FeedService' before initialization
at /Users/bytedance/Documents/demo/jiti-declare/module.ts:1:358
at /Users/bytedance/Documents/demo/jiti-declare/module.ts:1:372
at jiti (/Users/bytedance/Documents/demo/jiti-declare/node_modules/jiti/dist/jiti.js:1:196506)
at /Users/bytedance/Documents/demo/jiti-declare/entry.ts:1:90
at jiti (/Users/bytedance/Documents/demo/jiti-declare/node_modules/jiti/dist/jiti.js:1:196506)
at Object.<anonymous> (/Users/bytedance/Documents/demo/jiti-declare/start.js:5:17)
at Module._compile (internal/modules/cjs/loader.js:1085:14)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1114:10)
at Module.load (internal/modules/cjs/loader.js:950:32)
at Function.Module._load (internal/modules/cjs/loader.js:790:12)
It looks like a babel bug, simple reproduction:
import { transformSync } from "@babel/core";
import typescript from "@babel/plugin-transform-typescript";
let source = `
// entry.ts
export namespace smart_player_namespace {
export declare class FeedService {}
}
export type FeedService = smart_player_namespace.FeedService;
export const FeedService = smart_player_namespace.FeedService;
`;
let code = transformSync(source, {
babelrc: false,
configFile: false,
compact: false,
filename: "",
cwd: "/",
plugins: [[typescript, { allowDeclareFields: true }]],
}).code;
console.log(code);
console.log("----".repeat(20));
import fs from "fs";
fs.writeFileSync("d.mjs", code);
import("./d.mjs");
Output:
// entry.ts
export let smart_player_namespace;
(function (_smart_player_namespace) {
_smart_player_namespace.FeedService = FeedService;
})(smart_player_namespace || (smart_player_namespace = {}));
export const FeedService = smart_player_namespace.FeedService;
----------------------------------------------------------------------
file:///Users/hyrious/test/d.mjs:5
_smart_player_namespace.FeedService = FeedService;
^
ReferenceError: Cannot access 'FeedService' before initialization
As a reference, both TypeScript and esbuild don't generate this line, work as if there's no such declare statement.
babel/babel#14773
Seems the bug is not reproducable in latest babel/jiti 👍🏼