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’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error when loading modules without export using AMD and outFile options #18251

Closed
micnic opened this issue Sep 5, 2017 · 9 comments
Closed
Labels
Design Limitation Constraints of the existing architecture prevent this from being fixed

Comments

@micnic
Copy link
Contributor

micnic commented Sep 5, 2017

TypeScript Version: 2.5.2

Code

// a.ts
console.log('A');

// main.ts
import './a';

// main.js (output file of the command "tsc -m amd --outFile main.js main.ts")
console.log('A');
define("main", ["require", "exports", "./a"], function (require, exports) {
    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });
});

// When running the following error appear:
// Uncaught Error: Script error for "a", needed by: main

gist attached: https://gist.github.com/micnic/eea64a938858e9450bc6a2992cb0105c

Expected behavior:
It is expected that the content of the files which are imported without export statement is concatenated without being wrapped in a closure and they are not required anymore in the output file.

Actual behavior:
When running the code I get the error that the file ./a can not be found. This happens because these files are still required in the context of main.ts closure in the output file.

@kitsonk
Copy link
Contributor

kitsonk commented Sep 5, 2017

Duplicate of #18232

@micnic
Copy link
Contributor Author

micnic commented Sep 5, 2017

@kitsonk it is not really the same, the problem is that the a.ts is concatenated and after, when it is no more "visible", it is required like a normal module

@kitsonk
Copy link
Contributor

kitsonk commented Sep 5, 2017

It is the same, you are trying to load it as a module, but it is being emitted as global JavaScript, and thereby cannot be loaded as a module. Just because you are concatenating to a single file is immaterial.

@micnic
Copy link
Contributor Author

micnic commented Sep 5, 2017

Sorry, but you did not get my point, I created a gist for this use case: https://gist.github.com/micnic/eea64a938858e9450bc6a2992cb0105c

please download it as zip, unpack it, run tsc in the terminal in the directory, open the browser and check the browser console

@kitsonk
Copy link
Contributor

kitsonk commented Sep 5, 2017

I did get your point.

a.ts is being emitted as global/plain JavaScript, instead of a module that can be loaded. This is because TypeScript considers any TypeScript file without imports or exports as a global JavaScript file, not a module that can be loaded.

The outFile and the AMD target are red herrings to the root problem. Your problem would go away if you added:

console.log('A');

export let undefined;

to a.ts. Try it, you will notice it fixes your problem. But it is a workaround versus a solution.

@aluanhaddad
Copy link
Contributor

@kitsonk The linked code works fine when tsc emits individual files but fails when outFile is used. This behavior differs from tools such as r.js which emits a named define for a'.

@kitsonk
Copy link
Contributor

kitsonk commented Sep 5, 2017

@aluanhaddad depends on what the behaviour is though. Obviously console.log('A'); is a non-sensical construct. The transpiler is not emitting it as a module and that could cause problems depending on the use case. But yes, I can see how the behaviour changes between the outFile or not, but the root cause is still that it isn't being emitted as a module, which only exhibits itself when the files are concatenated.

@mhegazy
Copy link
Contributor

mhegazy commented Sep 5, 2017

The ts compiler defines a module as a file with at least one top-level import/export statement. a file with neither is considered a global script. these assumptions are needed to allow for correct parsing of the files, since modules are parsed in strict mode.
This is a problem with the module spec on TC39's side, that favored web loading over other tools like node, which makes loading modules non-statically determined. there is a proposal to add a paragma "use module"; to eliminate this ambiguity.
since modules with no imports or exports are rare, we recommend using export {}; to your file to force treating it as a module.

@mhegazy mhegazy added the Design Limitation Constraints of the existing architecture prevent this from being fixed label Sep 5, 2017
@micnic
Copy link
Contributor Author

micnic commented Sep 6, 2017

ok, thanks for the explanation, I think this issue can be closed

@micnic micnic closed this as completed Sep 6, 2017
@microsoft microsoft locked and limited conversation to collaborators Jun 14, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Design Limitation Constraints of the existing architecture prevent this from being fixed
Projects
None yet
Development

No branches or pull requests

4 participants