Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Forked typescript type checking #101

Closed
wants to merge 26 commits into from
Closed

Forked typescript type checking #101

wants to merge 26 commits into from

Conversation

davidmpaz
Copy link
Contributor

This PR fixes: #63 it should be possible to merge also with #99 directly.

Open points:

Regarding point .1 in #2

If this plugin is added. we need to check dependency is added using loader-features.js. This module name is getting name from loaders, we are not adding a loader here but a plugin. Maybe some more general module is needed for checking features?

After implementing this I realize that as soon as you require a module which doesn't exist node throws an error, we don't even go through error catch from encore. So possible solutions I see for this pending point are:

  1. We don't refactor loader-features.js file and we still will get a loud error when trying to use some plugin not installed. From error is clear whats need to be done.
  2. We refactor loader-features.js to be named more general and we include plugins dependencies also there as intended initially. But this way we need to check for missing packages earlier in WebpackConfig.js like I am doing now in this PR.

I like either solutions the same, I would like to get feedback on what do you guys think about it?

thanks in advance.

@weaverryan
Copy link
Member

I know what I'd like: option 2:

We refactor loader-features.js to be named more general and we include plugins dependencies also there as intended initially. But this way we need to check for missing packages earlier in WebpackConfig.js like I am doing now in this PR.

Even if the normal error from Node is pretty good, I'd rather be able to make the error specific to Encore - e.g. "You run yarn XYZ in order to use enableForkedTypeScriptTypesChecking".

I'll leave a comment that might help with the issue of where you place the "check" for the necessary packages.

Cheers!

@@ -11,6 +11,7 @@

const loaderFeatures = require('../loader-features');
const babelLoader = require('./babel');
const forkedTypesPluginUtil = require('../plugins/forked-ts-types');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When you require this file, it requires fork-ts-checker-webpack-plugin. And THAT causes the big Node error in case fork-ts-checker-webpack-plugin isn't installed. What you can do is move this require statement down - it doesn't need to be on top:

if (webpackConfig.useForkedTypeScriptTypeChecking) {
loaderFeatures.ensureLoaderPackagesExist('forkedtypecheck');

const forkedTypesPluginUtil = require('../plugins/forked-ts-types');

}

require is most commonly done on top, but it's not a requirement.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That was my first solution. I did not commit it because I was hidding a dependency in the execution path of the library. I guess that since we use it to report back an error it should be fine.

I'll take care of it. thanks!!

@davidmpaz
Copy link
Contributor Author

davidmpaz commented Jul 21, 2017

Btw @weaverryan ... any idea how can I deal with that timeout error I receive from functional.js tests on appveyor ? I am considering now whether remove that test or not :(

@davidmpaz
Copy link
Contributor Author

I believe that this timeout error on Appveyor and now Travis:

1) Functional tests using webpack Basic scenarios. TypeScript is compiled and type checking is done in separate process!:
     Error: Timeout of 8000ms exceeded. For async tests and hooks, ensure "done()" is called; if returning a Promise, ensure it resolves.

is related to the cached node_modules directory. I had same errors locally in non related tests (like now in travis) when changing branches which uses differents modules, after an npm install error was gone.

I will ignore them, after merging everything should be gone.

@weaverryan
Copy link
Member

@davidmpaz Now that I look at this (nice work btw), is there any disadvantage to just always adding the forked type checking, if fork-ts-checker-webpack-plugin is enabled? I'd like Encore to try to automatically apply as many sane optimizations as it can. So, when you apply ts loader (but don't have fork-ts-checker-webpack-plugin installed), we could add a "recommendation" console.log() that you'll have better performance if you install it (this would be the first time we have one of these "recommendations" comments - but it's an idea I'd like to do more to help educate the user).

@davidmpaz
Copy link
Contributor Author

thanks. Regarding disadvantages I can see in their docs:

It's very important to be aware that this plugin uses typescript's, not webpack's modules resolution. It means that you have to setup tsconfig.json correctly. For example if you set files: ['./src/someFile.ts'] in tsconfig.json, this plugin will check only someFile.ts for semantic errors. It's because of performance.

And i did noticed that the plugin expect a tsconfig.json file from here if not, error is thrown. As far I remember for the ts-loader is recommended but optional, not a requirement.

Besides that, nothing more come to my mind.

Copy link
Member

@weaverryan weaverryan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@davidmpaz Ah, very good! Then you've made the right decision to not enable it by default. I hesitate with these decisions (to do more automatic than we do now). But instead of that, let's educate the users whenever we can recommend that they opt into something else.

Cheers!

index.js Outdated
*
* This is a build optimization API to reduce build times.
*
*
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

extra line here

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What line is surplussing ? :)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We usually only have one empty (well *) line between the description and the start of the arguments. So, delete line 384 :).

index.js Outdated
* @param {Object} forkedTypeScriptTypesCheckOptions
* @return {exports}
*/
enableForkedTypeScriptTypesChecking(forkedTypeScriptTypesCheckOptions = {}) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We've made these options arguments callbacks everywhere else. Though it feels unnecessary here, I think we should do the same


if (!this.useTypeScriptLoader) {
throw new Error('TypeScript loader must be enabled. Call `enableTypeScriptLoader()` first.');
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can't remember if I made this comment before or not, but checks like this need to be moved to be during the config generation process. It should be fine to call enableTypeScriptLoader() and enableForkedTypeScriptTypesChecking() in whatever order.

forkedtypecheck: {
method: 'enableForkedTypeScriptTypesChecking()',
packages: ['typescript', 'ts-loader', 'fork-ts-checker-webpack-plugin'],
description: 'check TypeScript types in separate process'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in a separate...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you refer to make a feature checker for plugins I have some work related to that. I just want to start including something in main stream before make another PR for the loader features itself. For now I used like it is.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That would be cool - but I meant something simpler here :). Just a language tweak in the description: change in separate process to in a separate process - minor English thing!

// add forked ts types plugin to the stack
const forkedTypesPluginUtil = require('../plugins/forked-ts-types');
forkedTypesPluginUtil(webpackConfig);
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about logging a recommendation here to enable this feature for faster type-checking? We now have a logger.js module that can be used for this (though I might add a new method on that - recommendation() - instead of using debug().

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When we get that recommendation() method we can add it yes.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's in #116 - we'll probably merge this first. If so, I'll add the warning after #116

package.json Outdated
@@ -34,6 +34,7 @@
"css-loader": "^0.26.2",
"extract-text-webpack-plugin": "^3.0.0",
"file-loader": "^0.10.1",
"fork-ts-checker-webpack-plugin": "^0.2.7",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should be in devDependencies

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will get a linting error then. I even reported that in TypeStrong/fork-ts-checker-webpack-plugin#34 but it seems to be right like that.

Honestly I can not argue much about it since I still don't get right eslint rules :(

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, this makes sense. Congrats! You were the first to hit this issue :). Basically, it's quite often for Encore to have optional features. Think about sass-loader - we don't have that in our dependencies because we force the user to add this manually. We add it in devDependencies just so we can use it in our tests.

But fork-ts-checker-webpack-plugin is different, because (unlike all the optional loaders), we explicitly require this module (for loaders, you just mention the loader name and webpack requires it later - so the linter doesn't pick up on this).

tl;dr; The linter is correct in a sense: Encore is using this package in its actual code, not just in its tests. But it's wrong because we're manually checking to make sure this package exists before using it.

So, add // eslint-disable-line after the require line in forked-ts-types.js to silence this lint problem. THEN put it in devDependencies :)

}).to.throw(
'TypeScript loader must be enabled. Call `enableTypeScriptLoader()` first.'
);
});
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good test, but should live somewhere else after the corresponding code moves.

// TODO find a way to confirm forked is used. Maybe terminal output?
// Output:
// Starting type checking service...
// Using 1 worker with 2048MB memory limit
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm. Well, we have other tests that confirm that the config is setup correctly. Is it enough to know just that this test didn't blow up? Is there any reasonable way it could blow up? I'm probably ok without adding anything additional.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know actually. That's why I did add the comment. Will check anyways.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's just remove these comments for now and leave the test as-is.

Copy link
Collaborator

@Lyrkan Lyrkan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just some uses of let that can be replaced by const.


'use strict';

let ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

const instead of let

const WebpackConfig = require('../../lib/WebpackConfig');
const RuntimeConfig = require('../../lib/config/RuntimeConfig');
const tsLoader = require('../../lib/loaders/typescript');
let ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

const instead of let

* @return {void}
*/
module.exports = function(webpackConfig) {
let config = Object.assign({}, webpackConfig.forkedTypeScriptTypesCheckOptions);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

const instead of let

Add plugin at the time typescript loader is added.
As soon as we require a module that doesn't exist we get node error:
"Cannot find module 'module-name'".
Add dependency and update yarn.lock
This is moved to typescript loader.
equire plugin module after packages check is done to avoid node error
and print prettyfied error from encore.
Avoid timeout errors in Appveyor. Somehow x86 architecture
is making mocha to timeout.
Call done callback before time expire.
Make module export function to meet similar signatures as
for PR #99
@weaverryan
Copy link
Member

Thank you David! If I have time this morning, I'll try to add the "recommendation" log to "advertise" this when you use ts-loader

@weaverryan weaverryan closed this in 2cae5df Aug 5, 2017
weaverryan added a commit that referenced this pull request Aug 5, 2017
…ly (weaverryan)

This PR was merged into the master branch.

Discussion
----------

Adding tests for the logger and cleaning up a bit internally

... also added the `recommendation` method, which we will use in #101.

Commits
-------

7ecfece Adding tests for the logger and cleaning up a bit internally
@davidmpaz davidmpaz deleted the forked-typescript branch August 13, 2017 16:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add support for separate type checking in Type Script
3 participants