Skip to content
This repository has been archived by the owner on Jan 26, 2019. It is now read-only.

Unable to compile a project when using scripts v2.10.0 and up #246

Open
codeaid opened this issue Feb 1, 2018 · 5 comments
Open

Unable to compile a project when using scripts v2.10.0 and up #246

codeaid opened this issue Feb 1, 2018 · 5 comments

Comments

@codeaid
Copy link

codeaid commented Feb 1, 2018

Is this a bug report?

Yes

Can you also reproduce the problem with npm 4.x?

Yes

Which terms did you search for in User Guide?

Not really relevant, it's a TypeScript specific issue. Searched for module and resolve but there's nothing that would help.

Environment

  1. npm ls react-scripts-ts (if you haven’t ejected): 2.10.0, **

  2. node -v: 8.9.4

  3. npm -v: 5.6.0

  4. yarn --version (if you use Yarn): 1.3.2

  5. npm ls react-scripts-ts (if you haven’t ejected): Duplicated question (same as 1)?

  6. Operating system: Ubuntu

  7. Browser and version (if relevant): Not relevant

Steps to Reproduce

I am working on a project that was created using create-react-app and react-scripts-ts a while ago. Everything was compiling with no issues until I decided to update react-scripts-ts to the latest version.

The way the project is structured is as follows:

  • Every component resides in a separate directory and generally consists of the following files:

    • index.tsx - main component file
    • types.ts - component property and state interfaces declared inside a module (examples below)
    • styles.css - component specific stylesheets
  • Type definition files have the following format:

    declare module 'component-types' {
        export interface IMyComponentProps {
            // ...
        }
    
        export interface IMyComponentState {
            // ...
        }
    }
  • Main component file import dependencies and type declarations at the top of the file:

    import * as React from 'react';
    import {IMyComponentProps, IMyComponentState} from 'component-types';
    import './styles.css';
    
    export class MyComponent extends React.Component<IMyComponentProps, IMyComponentState> {
        // ...
    }

Previously there were no warnings while compiling, however, now I am getting the following message:

ts-loader: Using [email protected] and /var/www/my-project/tsconfig.json
No valid rules have been specified

That is a message that leads me to think that the loader is not picking up the tslint.json file for some reason.

As annoying as it is, I could live with that warning, however the bigger problem is that I am unable to compile my project any more as I am getting the following error:

Failed to compile.

Module not found: Error: Can't resolve 'component-types' in '/var/www/my-project/src/components/MyComponent'

There are plenty more of the same errors for lots of components in the developer tools console so it's not just one component.

I have tried different combinations of typescript and react-scripts-ts and none of them work. TypeScript 2.7.1 works with scripts version 2.8.0 so it's not related to TypeScript either.

Looking at the changes between 2.8.0 and 2.10.0, it looks like the biggest one is introduction of fork-ts-checker-webpack-plugin. Could that be something that brakes things?

Expected Behavior

Successful build just like with react-scripts-ts versions up to 2.8.0 (including).

Actual Behavior

See Steps to Reproduce.

Reproducible Demo

I am unable to supply any demo code as it's internal company code.

npm run build output

$ npm run build

> [email protected] build /var/www/my-project
> react-scripts-ts build

Creating an optimized production build...
Starting type checking and linting service...
Using 1 worker with 2048MB memory limit
ts-loader: Using [email protected] and /var/www/my-project/tsconfig.json
No valid rules have been specified
Failed to compile.

Module not found: Error: Can't resolve 'cms-types' in '/var/www/my-project/src/components/MyComponent'


npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! [email protected] build: `react-scripts-ts build`
npm ERR! Exit status 1
npm ERR! 
npm ERR! Failed at the [email protected] build script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
@DorianGrey
Copy link
Collaborator

These are two different issues.

  1. The no valid rules have been specified - this warning is emitted by tslint, indicating that the list of parsed rules is empty:
    https://github.com/palantir/tslint/blob/a4dc874a3fd8e9d924977dfdd25fb334eb6d49f7/src/ruleLoader.ts#L78-L81
    The rules are parsed here:
    https://github.com/palantir/tslint/blob/a4dc874a3fd8e9d924977dfdd25fb334eb6d49f7/src/ruleLoader.ts#L35-L57
    Being able to have a look at you tslint.json would be helpful. The plugin used to execute tslint by default picks up the tslint.json in the project's root directory.
  2. The error is caused by a module resolution failure. With the information provided, it's hard to tell. You either have not defined cms-types as a module correctly, or the definition is not picked up and thus fails to resolve. I'm not sure why you are creating a types.ts file including a module declaration for each component, though. Why not define the interfaces in that file and use a relative import?

It's hard to tell or figure out more with a reproduction, though.
Besides, the current version is 2.13, not 2.10. You might give the most recent version a try.

@codeaid
Copy link
Author

codeaid commented Feb 2, 2018

As the issue title says - it's happening with versions of react-scripts-ts starting with 2.10.0 and up to (currently) 2.13.0 inclusive.

I went back to debugging the problem after I posted the issue. I created an new create-react-app project using react-scripts-ts and updated it to use TypeScript 2.7.1. I then proceeded to move files from my project into the new one. It was all fine until I included some certain components.

Long story short - after lots of swearing and experimenting, I discovered that the one thing those components had in common was that they were exporting const enums from ambient modules like this:

declare module 'cms-types' {
    export interface ISomeInterface {
        foo: string;
    }

    export const enum SomeType {
        Foo = 'foo',
        Bar = 'bar',
    }
}

The way I managed to fix it is by moving the enum declaration to a separate file:

// some/path/to/enums.ts
export const enum SomeType {
    Foo = 'foo',
    Bar = 'bar',
}

...and importing it as from a normal module:

import {ISomeInterface} from 'cms-types';
import {SomeType} from 'some/path/to/enums';

// ...

The ambient module declaration only contained the interfaces after that:

declare module 'cms-types' {
    export interface ISomeInterface {
        foo: string;
    }
}

Additionally, it does not show the "No valid rules have been specified" warning anymore after moving enums to separate files.

I am still baffled as to why it works with react-scripts-ts before and including v2.8.0 but breaks after updating to 2.10.0+. It is definitely not related to the version of TypeScript as everything works with 2.6 as well as 2.7.

Any ideas on what could cause this behaviour? I certainly can't think of any without knowing the internals of react-scripts-ts. Could it potentially have something to do with fork-ts-checker-webpack-plugin that was added between those two versions?

@DorianGrey
Copy link
Collaborator

Potentially, yes - but not necessarily in an unintended way.
Recently, #245 was reported, and the reason for this issue was a tsconfig that was not fully taken into account before this plugin was added. It uses a ts.Program instance under the hood and thus strictly takes care of this configuration, which differs from the previous behavor - this includes module resolution as well. Thus, at least the failed module resolution points towards a problem with the typescript configuration in use. It would be useful to be able to have a look at your tsconfig.json.

Other steps - it's somewhat easy to figure out if this issue only occurs due to the added plugin, or if one of the other updates might have caused this.
To point this out, please modify the following code parts in your installed version of react-script-ts as follows:
1: Set transpileOnly to false here:

// Compile .tsx?
{
test: /\.(ts|tsx)$/,
include: paths.appSrc,
use: [
{
loader: require.resolve('ts-loader'),
options: {
// disable type checker - we will use it in fork plugin
transpileOnly: true,
},
},
],
},

2: Remove the fork-ts-checker-webpack-plugin here:
// Perform type checking and linting in a separate process to speed up compilation
new ForkTsCheckerWebpackPlugin({
async: false,
watch: paths.appSrc,
tsconfig: paths.appTsConfig,
tslint: paths.appTsLint,
}),
],

If the start task works fine afterwards, the issue is definitely related to the more strict mode this plugin applies.

Besides, I don't think this kind of usage of ambient modules is intended - their intention is to use them for creating definitions for javascript modules (libraries), and not for local modules that don't even exist or contain any executable source code after transpilation.

@codeaid
Copy link
Author

codeaid commented Feb 3, 2018

Thanks for detailed explanation! Much appreciated!

Firstly, you can find my tsconfig.json, tslint.json and package.json files in this gist if still needed.

Having read more about modules lately I do realise that my current setup is probably not 100% correct but I can't really think of where else could I put my component interface definitions. I don't want to have them in the same file as the component definition and I would prefer not to move them into some globally accessible directory (e.g. *.d.ts files in ./typings) either.

I'll try applying your suggestions on Monday when I'm back at work but even if they don't work, I have managed to fix my build by just moving all my enum definitions to separate files, which actually makes more sense now.

I'll keep you posted! It would be interesting to get to the bottom of this problem.

@xumix
Copy link

xumix commented Jun 12, 2018

Here is the root cause: TypeStrong/ts-loader#331

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants