jiti icon indicating copy to clipboard operation
jiti copied to clipboard

Cannot access 'xxx' before initialization

Open as17744 opened this issue 3 years ago • 2 comments

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)

as17744 avatar Jun 16 '22 06:06 as17744

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.

hyrious avatar Jul 15 '22 02:07 hyrious

babel/babel#14773

hyrious avatar Jul 20 '22 09:07 hyrious

Seems the bug is not reproducable in latest babel/jiti 👍🏼

pi0 avatar Sep 06 '22 09:09 pi0