Skip to content

When transpileOnly is enabled, ts-loader leaves in re-exports of types, causing webpack 4 to warn about export not being found #751

@univerio

Description

@univerio
Contributor

Expected Behaviour

For a project like this:

// bar.ts
export {IFoo, FOO} from "./foo";
export type IBar = {};
// foo.ts
export type IFoo = {};
export const FOO = 1;
// index.ts
import {FOO, IFoo, IBar} from "./bar";

declare function foo(i: number): IFoo;
declare function bar(): IBar;
foo(FOO);
bar();

Regardless of whether transpileOnly is enabled, the output for bar.ts should be (assuming module=ESNEXT):

export var FOO = 1;

Actual Behaviour

The actual output is:

export { IFoo } from "./foo";
export var FOO = 1;

which causes webpack to complain:

WARNING in ./src/bar.ts
1:0-34 "export 'IFoo' was not found in './foo'
 @ ./src/bar.ts
 @ ./src/index.ts

When transpileOnly is off, the module is correctly emitted. This may very well be a compiler bug, but I'm not sure how to use tsc to reproduce this.

Steps to Reproduce the Problem

git clone https://github.com/univerio/ts-loader-type-export-issue
cd ts-loader-type-export-issue
yarn
./node_modules/webpack-cli/bin/webpack.js

Location of a Minimal Repository that Demonstrates the Issue.

https://github.com/univerio/ts-loader-type-export-issue

Activity

johnnyreilly

johnnyreilly commented on Mar 24, 2018

@johnnyreilly
Member

This may very well be a compiler bug, but I'm not sure how to use tsc to reproduce this.

I suspect this is a compiler issue yes. That said there may be good reason for it. I'd suggest asking a question on the Typescript project to confirm if this is expected behaviour or not. ts-loader is doing nothing special here; just hooking into the Typescript compiler API

univerio

univerio commented on Mar 26, 2018

@univerio
ContributorAuthor

I think I understand it now. I think it has to do with the fact that transpileOnly uses ts.transpileModule, which is essentially equivalent to turning on isolatedModules. When compiling each module separately, the compiler does not have enough information to know whether an import is a type or not (see microsoft/TypeScript#15231), so while it eliminates imports that are never used in a value position (which works for imported types that are not exported), it cannot know whether an export is a type or not. So, fundamentally, ts.transpileModule is incompatible with type re-exports.

This issue has cropped up now because webpack 4 warns about these invalid exports, but the final bundle otherwise works fine. Perhaps there's an option in webpack to silence these warnings?

johnnyreilly

johnnyreilly commented on Mar 26, 2018

@johnnyreilly
Member

Thanks for investigating and reporting back - super helpful! It might be worth inquiring against the webpack repo for such an option and linking back to this. I'm not aware of an option myself but that doesn't mean it doesn't exist!

univerio

univerio commented on Mar 26, 2018

@univerio
ContributorAuthor

Found the option:

{
  stats: {
    warningsFilter: /export .* was not found in/,
  }
}

Perhaps we can add it to the readme?

johnnyreilly

johnnyreilly commented on Mar 27, 2018

@johnnyreilly
Member

Sure - send a PR!

FourwingsY

FourwingsY commented on Apr 11, 2018

@FourwingsY

Hi, I met this problem not as warning but as error.
So I cannot suppress it. Anybody has an idea?

univerio

univerio commented on Apr 11, 2018

@univerio
ContributorAuthor

@FourwingsY Do you have a plugin that converts warnings into errors?

FourwingsY

FourwingsY commented on Apr 11, 2018

@FourwingsY

@univerio Oh yes i got it. I've set config.module.strictExportPresence = true on webpack config. Thanks a lot!

enoshixi

enoshixi commented on Jun 25, 2018

@enoshixi

This also works for me and gets the compiler to remove the type export all together:

import { IFoo } from "./foo";
export type IFoo = IFoo;

22 remaining items

Loading
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @bjeanes@Jessidhia@johnnyreilly@univerio@Bnaya

        Issue actions

          When transpileOnly is enabled, ts-loader leaves in re-exports of types, causing webpack 4 to warn about export not being found · Issue #751 · TypeStrong/ts-loader