Ts-loader: Relative import with targeting to es6

Created on 28 Oct 2015  路  26Comments  路  Source: TypeStrong/ts-loader

I got stuck with loading relative modules and targeting ts compiler to es6.
Example 1:

import dep = require('./file.ts') // causes error TS1202: Import assignment cannot be used when targeting ECMAScript 6 or higher. Consider using 'import * as ns from "mod"', 'import {a} from "mod"' or 'import d from "mod"' instead.

import dep from './file.ts' // causes error TS2307: Cannot find module './file.ts'.

Changing target to es5 makes _both_ of variances work. Any ideas to get them work on es6 target?

bug

All 26 comments

You can't use import ... = require() when targeting ES6. That's a TypeScript rule (as you can see from TS1202). You have to use import ... from '...'.

You also need to remove the extension from the module. So you should use:

import dep from './file';

Yes, thank you, it works. But only for .ts files. When I want to import .tsx files, compiler fails with "error TS2307: Cannot find module" with and without extension in import .. from statement. I have created example repo to show error: https://github.com/Strate/webpack-typescript-example

I have found solution: adding "moduleResolution": "node" to tsconfig.json does the job.

@Strate, make your resolve in webpack.config.js like this and you'll be fine:

resolve: {
      // Add `.ts` and `.tsx` as a resolvable extension.
      extensions: ['', '.webpack.js', '.web.js', '.ts', '.tsx', '.js']
  }

"moduleResolution": "node" should be the default. What version of TypeScript are you using? Are you using the nightly?

@jbrantly

% tsc --version
message TS6029: Version 1.6.2

Thanks. I'll try to replicate the original issue. You really shouldn't need to specify moduleResolution.

You really shouldn't need to specify moduleResolution.

Only true if --module commonjs is set. Otherwise user needs to specify ... I think :rose:

ts-loader automatically sets --module commonjs for ES3/5 target. It doesn't for ES6 target. Something to look at for sure.

So I've looked into this a bit and there are multiple cascading issues. The first issue is that there is a bug in ts-loader where the webpack lookup was failing (ts-loader first tries to resolve a file using webpack's resolution strategy). Since that was failing, the loader fell back on TypeScript's module resolution strategy. In this case TypeScript was unable to find the .tsx file because the jsx option was not specified in the compiler options, so that failed as well resulting in the "cannot find module" message. However, if you switched moduleResolution to node then TypeScript magically decided to include .tsx files in its lookup. Kind of weird if you ask me and possibly a bug that .tsx extension handling is done differently between the two strategies. In any case, by fixing the original bug the TypeScript resolution "bug" doesn't come into play.

I've opened #102 to resolve.

Fixed in v0.7.0. Thanks for reporting!

v0.7.0 broke my relative imports.

tsconfig.json

{
    "version": "1.6.2",
    "compilerOptions": {
        "target": "ES5",
        "module": "commonjs",
        "noImplicitAny": false,
        "jsx": "react",
        "sourceMap": true
    }
}

webpack.config.js

module.exports = {
    output: {
        path: '../Content/apps',
        filename: '[name].app.js', // Template based on keys in entry above
    },
    debug: false,
    watch: false,
    plugins: [
    ],
    module: {
        loaders: [
            {
                test: /\.tsx?$/,
                exclude: /node_modules/,
                loader: 'ts-loader'
            },
            {
                test: /\.jsx?$/,
                exclude: /node_modules/,
                loader: 'babel-loader'
            }
        ]
    },
    resolve: {
        extensions: ['', '.js', '.jsx', '.ts', '.tsx'],
        modulesDirectories: ['node_modules', 'js']
    }
};

Error:

ERROR in ./js/common/ts/Components/List.tsx
(16,8): error TS2307: Cannot find module './../Framework'.

ERROR in ./js/common/ts/Components/List.tsx
(153,3): error TS2347: Untyped function calls may not accept type arguments.

ERROR in ./js/common/ts/Components/List.tsx
(154,3): error TS2347: Untyped function calls may not accept type arguments.

ERROR in ./js/apps/fylkesmann/klagebehandling/Components/Klager/Klager.tsx
(24,33): error TS2307: Cannot find module '../Main'.

@thrandre Sorry to hear that. Could you post your file paths (for example, is it ./js/common/ts/Framework.ts?) and also what your import statements look like in List.tsx and Klager.tsx?

No biggie, just wanted to report it.

Project hierarchy:

js/
    | tsconfig.json
    | apps/
        | ...
            | Components
                | Klager.tsx
            | Main.tsx
    | common/
        | ts/
            | Framework.ts
            | Components/
                | List.tsx

Imports in Klager.tsx

import { MapStoresToProps, MapPropsOnChange, PropEqualityComparer, ActionState } from "../../../../../common/ts/Framework";

import KlageList from "./KlageList";
import FormatFilter from "./FormatFilter";

import { Klage } from "../../Typings/Klage";

import KlageStore from "../../Stores/KlageStore";
import KlageAppStore from "../../Stores/KlageAppStore";

import KlageActions from "../../Actions/KlageActions";
import KlageAppActions from "../../Actions/KlageAppActions";

import KlageTagGenerator from "../../Utils/KlageTagGenerator";

import { IMainRouteProps } from "../Main";

I'm waiting for the TypeScript team to fix a module resolution bug in the TS Language Service as I would prefer using absolute paths. This stuff - "../../../../../common/ts/Framework" - is killing me.
This works fine in v0.6.0 and 0.6.1. Thanks for rapid response!

Alright thanks! Working on duplicating now.

Actually, super quick, could you try swapping around your file extensions in your webpack config? Instead of doing ['', '.js', '.jsx', '.ts', '.tsx'] could you do ['', '.ts', '.tsx', '.js', '.jsx']?

Sorry, no luck.

@thrandre So far I've been unable to duplicate, so I want to try a different route. I've attached a special build of ts-loader that has some additional logging. Could you replace index.js with this file and run webpack > debug.txt 2>&1 and post the results?

I had to dump the whole console output (on windows). Hope this will suffice.
https://gist.github.com/thrandre/78a01850f761fd01c18b#file-tsload-log

Awesome! That was really helpful. I believe it's a Windows-only issue (whoops! the one thing travis-ci can't test :frowning:) I believe I've got a fix here. Could you try it and confirm? If it still doesn't work could you once again post the log?

It appears to be working now. Good job, sir!

The Windows-compatible version of this fix is now published in v0.7.1. :grin:

@thrandre Sorry for the trouble, and thanks a ton for reporting and helping identify the issue!

@jbrantly,

Is it worth setting up ts-loader to run CI on a Windows platform as well as Travis? Appveyor is Windows CI and has been pretty good in my experience. I haven't directly investigated but I imagine that you can plug as many CI providers into a repo as you like.

Having it build on Windows as well as *nix might catch issues like this a little earlier. (I'd be happy to help if you think it'd be useful)

@johnnyreilly Absolutely! I wasn't aware of Appveyor but I'll take a look. Thanks for the info.

No problem! I've found AppVeyor it's very plug-and-play but also completely customisable with an appveyor.yml file. If you'd like an example of project that's running a JavaScript build on a windows machine then you could take a look at this:

https://github.com/johnnyreilly/globalize-so-what-cha-want

Give me a shout if you'd like a hand.

Was this page helpful?
0 / 5 - 0 ratings