61

I'm trying to use export and import but it not working I get an error

Here is my code HTML :

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
    @RenderBody()

    <script src="~/scripts/user.js"></script>
    <script src="~/scripts/main.js"></script>
</body>
</html>

User.ts :

export class User {
    firstName: string;
    lastName: string;
}

main.ts

import { User } from "./user";

Here is also screenshot of exception :

enter image description here

Iris
  • 1,436
  • 3
  • 14
  • 29

7 Answers7

37

You have a couple of options:

Option 1: Use a module loader like Webpack, Browserify, etc.

Option 2: If you just want to compile *.ts to *.js without any module imports or exports, set compilerOptions.module to "none" in your tsconfig.json. Note that you won't be able to export/import modules when you set compilerOptions.module to "none".

James W.
  • 154
  • 3
  • 13
Saravana
  • 37,852
  • 18
  • 100
  • 108
  • 1
    Can I use Webpack in ASP.NET ? – Iris Apr 18 '17 at 13:26
  • 1
    You can. Much easier with ASP.NET Core now. There are plenty of examples online. – Saravana Apr 18 '17 at 13:28
  • 6
    or simply use references, than it works without any module loader and as commonjs, and you don't want to load hundreds of js files in your html i think, so only output 1 js file – TypedSource Apr 18 '17 at 17:19
  • I set compilerOptions.module to ESNext and it solved the issue, allowing me to use "export" like asked in the question. – mwryl Mar 03 '21 at 10:09
19

try the following changes

HTML:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
    @RenderBody()

    <!-- <script src="~/scripts/user.js"></script> --> <!-- not longer needed -->
    <script src="~/scripts/main.js"></script>
</body>
</html>

tsconfig.json

{
  "compilerOptions": {
    "module": "commonjs",
    "target": "es5",
    "sourceMap": true,
    "outFile": "~/scripts/main.js",
    "lib": [
      "dom",
      "es2015",
      "es5",
      "es6"
    ]
  }
}

with this config your output is only one js file what can be uglified wunderfull, containing all referenced files in the main.ts. i just don't know if ~/ works or if you have to set the path relative to the config file, i'm not working with linux.

User.ts

class User {
    firstName: string;
    lastName: string;
}

Main.ts:

/// <reference path="User.ts" />

// import { User } from "./user"; // not needed if referenced
console.log(new User());

all reference declarations have to be written at the beginning of the file

TypedSource
  • 708
  • 4
  • 12
  • 3
    Wow, I've been searching on import vs reference for too many hours now, thank you so much! This was the root of my problem. – joe Apr 19 '17 at 16:25
  • 4
    This answer doesn't work for me, I get this problem: https://stackoverflow.com/questions/35963346/only-amd-and-system-modules-are-supported-alongside-out – Nick Coad Jun 02 '17 at 04:52
  • @NickCoad looks like a problem with VisualStudio, i use Atom, PHPStorm and IntelliJ and all works fine. – TypedSource Jun 18 '17 at 07:02
  • @TypedSource I'm not doing this in Visual Studio, I'm doing it in the command line. – Nick Coad Jun 19 '17 at 00:36
  • Struggled with this as well. Finally got it working with the module type set to "system". The commented out import line is required! I pushed a working example up to `github: https://github.com/medington/ts-reference`. – Mark Edington Jul 21 '17 at 16:25
  • Also make sure your don't have "export" in front of the `User` class. – Mark Edington Jul 21 '17 at 17:30
  • 2
    I get `error TS6082: Only 'amd' and 'system' modules are supported alongside --outFile` – CodyBugstein Jul 16 '19 at 14:16
  • I changed the tsconfig.json to use system instead of commonjs, included system.js in and then added a – Gerry Mar 08 '20 at 15:34
9

TypeScript by default uses node module resolution. Node.js / CommonJS uses exports keyword. However, CommonJS doesn't run in browser without a module loader or module bundler. Hence, you need browserify or webpack to get it running in browser.

Check out this link https://www.typescriptlang.org/docs/handbook/gulp.html

You can also set module setting to none in compiler options section in tsconfig.json:

{ "compilerOptions": { "target": "es5", "module": "none" } }

Ibro
  • 180
  • 3
  • 2
    this isn't correct. i run CommonJS in my browser without any problems. you can't use export and import in browser without an module loader, thats correct. – TypedSource Apr 18 '17 at 16:15
  • You are correct, I corrected my answer to be more explicit about it. You would need a module loader or module bundler to get CommonJS working in browser. Thanks. – Ibro Apr 19 '17 at 08:14
4

I now use Parcel to do the ugly stuff of transcoding etc. My easiest config is the following:

tsconfig.json

{
    "compilerOptions": {
        "target": "es5",
        "sourceMap": true,
        "noImplicitAny": true,
        "noImplicitReturns": true,
        "lib": [
            "es2015",
            "es5",
            "es6",
            "dom"
        ],
        "noUnusedLocals": true,
        "module": "commonjs",
        "strict": false
    },
    "include": [ "lib/*", "./main.ts" ]
}

and in your HTML file, instead of importing the '.js', simply import the '.ts', like this:

<script src="main.ts"></script>

then, run Parcel with this command line:

parcel index.html

the Parcel bundler will create a dist directory containing all your needed files (html and transcoded JavaScript) and it will run a local webserver at:

http://localhost:1234

with hot module reloading (in your browser window).

When you finish your work, you just have to deploy the dist directory ;-)

Fabio Rotondo
  • 390
  • 2
  • 10
2

Similar to TypedSource's answer, but if you can't or don't want to output into one js file you can do the following:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
    @RenderBody()

    <script src="~/scripts/user.js"></script>
    <script src="~/scripts/main.js"></script>
</body>
</html>

User.ts :

class User {
    firstName: string;
    lastName: string;
}

main.ts

/// <reference path="User.ts" />

// import { User } from "./user"; // not needed if referenced & User.js file is loaded
console.log(new User());
Michael
  • 2,825
  • 3
  • 24
  • 30
1

This was my story:

I had the same problem because the browser uses modern export/import statement, while Typescript uses the default commonJS. So, in the tsconfig.json file, set the following changes:

target: "es2015",

module: "es2015",

I think if you use BabolonJS,it may be better to set "moduleResolution" to "node" explicitly, however it may make no difference.

Nadeem Taj
  • 1
  • 4
  • 21
  • 1
    Hi Mehdi. Firstly, thank you for your contribution. Perhaps you could improve it by framing the settings in a code block and making it clearer where in the essential code to apply those changes. All contributions are valuable, so it's a worthwhile effort to present yours in the most helpful way possible. In doing this you will increase the usability of your suggestions and improve the chances of receiving upvotes. You might consider taking a look at the other answers to provide insight and inspiration in how to format your contribution. – quinny Jul 29 '21 at 11:56
-1

This worked for me:

my-enum.ts

const MyEnum = {
'test': 456,
'Default': 123
}

Component.ts

import * as MyEnum from 'my-enum';
Yonatan Ayalon
  • 1,959
  • 18
  • 19