11

This is how my tsconfig.json file looks:

{
    "compileOnSave": true,
    "compilerOptions": {
        "module": "amd",
        "noImplicitAny": false,
        "removeComments": false,
        "preserveConstEnums": true,
        "strictNullChecks": true,
        "sourceMap": false
    }
}

I have a typescript file named a.ts which is an AMD module (I'm using requirejs), which looks like:

export function a() {
    var a = {
        b: 5
    };
    return a;
}

The compiled Javascript files looks like:

 define(["require", "exports"], function (require, exports) {
    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });
    function a() {
        var a = {
            b: 5
        };
        return a;
    }
    exports.a = a;
 });

I need my generated JavaScript file to be:

define(function () {
    "use strict";
    var a = {
        b: 5
    };
    return a;
});

So I need to
a) Remove the Object.defineProperty(exports, "__esModule", { value: true }); line
b) Remove the require and exports dependencies from define
c) Not having an internal function "a" and then expose "a" on exports, but rather simply return "a" object in the a.js file

What changes do I need to make to tsconfig.json and a.ts files to get the desired Javascript file or something closer to it, any improvements from current a.js towards what I need would be great, even 1 or 2 out of 3 requirements.

One way is to make a.ts exactly like my desired a.js file and then compile, but I must use export statement way of making amd module due to another unrelated requirement. Thanks for reading till here. Please help.

John Doe
  • 328
  • 3
  • 12
  • 1
    Possible duplicate of [Typescript AMD Target Resolving to CommonJS](https://stackoverflow.com/questions/46894234/typescript-amd-target-resolving-to-commonjs) – Aluan Haddad Nov 15 '17 at 01:03
  • @AluanHaddad Yeah that's seems like a duplicate. So this means there's no way ? If not of preventing my function on exports objects, there must be some way to remove the Object.defineProperty line and require and exports dependencies, a) and b) in my question above ? – John Doe Nov 15 '17 at 01:31

1 Answers1

7

Your export issue can easily be fixed by using the export = syntax. If you code your module with this:

var a = {
  b: 5
};

export = a;

It is transpiled to this:

define(["require", "exports"], function (require, exports) {
    "use strict";
    var a = {
        b: 5
    };
    return a;
});

Note that you also lose the creation of the __esModule property.

The rest of your question duplicates another question. In brief, the TypeScript compiler provides no option to avoid emitting the require and exports dependencies. You have to process the emitted code on your own if you want to remove them.

Louis
  • 146,715
  • 28
  • 274
  • 320
  • 1
    Thanks. That solved it. The require and exports dependencies are removed when I run amdclean. I'm new to typescript so please bear with me. This solved the case when module returns an Object literal. Can you give me some insight or a little code snippet when my module returns a function, then what do I export ? I am confused since I was using define earlier e.g. define([ ],function() {var func = function() {}; return func;}); Also what about the dependencies ? Can I write import('myDep'); directly above the module so that compiled file still satisfies my original conditions a) and b) ? – John Doe Nov 15 '17 at 04:17
  • If you want to return a function you can do `export = function myFunction() { /* ... */ }`. The `export = ...` syntax means "I want what is on the right hand side to be the module's value". In AMD, this translates to `return ...`. In CommonJS, it would be `module.exports = ...`. You can export anything this way: objects, functions, primitives, etc. Regarding `import`, your `import` statement will not *by itself* cause `tsc` to add back the `__esModule` property or make it impossible to remove the `require` and `exports` dependencies. – Louis Nov 15 '17 at 11:56
  • 1
    I'm a perplexed by your use of `amdclean`. (I assume you are talking about [this](https://github.com/gfranko/amdclean) tool). I've not used it, but from what I read, it turns AMD code into non-AMD code. If your end result is not AMD, then why have `tsc` output AMD modules in the first place? You could output CommonJS modules and avoid the whole issue with `__esModule` and the undesired dependencies. – Louis Nov 15 '17 at 11:59
  • Yes AMD-clean does exactly that but it produces plain JS code after removing AMD components, and also without any module.exports etc. statement so it's not generating NodeJS code either.Please explain on a more fundamental level. The main purpose of using RequireJS was to make the code modular and recursively load dependencies of a module and its dependencies' dependencies and so on. I have no requirement to serve the final program as a npm module to anyone, and I am running the generated JS modules on the browser. I reckon browserify does that for node modules but I think that would be too – John Doe Nov 15 '17 at 12:36
  • complex. But I'm open to all help which can reduce the complexity on my project overall. Please advice if using webpack or browserify and then bundling node modules for running on browser would have some advantage over simply make a single file by running requirejs on the generated AMD modules and simply using that file. And also what other factors I've overlooked. Thanks in advanced. – John Doe Nov 15 '17 at 12:40
  • 1
    RequireJS and AMD modules are super-useful in some contexts. However, I would not use AMD *unless* I need to load at runtime modules whose identity is not known *until* runtime. Otherwise, I'd just output everything as CommonJS modules and use Webpack to produce the final bundles. Also, when the time comes to add contributors or get help from outside, you have a better chance to find people who know Webpack, than people who know `amdclean`. I'm a case in point: I've written complex Webpack configurations and can help with Webpack problems but I've never ever used `amdclean`. – Louis Nov 15 '17 at 13:08