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
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
56f2099
Add type script type checking plugin public API
davidmpaz Jul 18, 2017
da5f026
Implement type checking plugin in encore configuration
davidmpaz Jul 18, 2017
8ceed5c
Add features needed by type checking plugin
davidmpaz Jul 18, 2017
2b9e4c5
Add plugin implementation integrating checker in encore
davidmpaz Jul 18, 2017
fd37f05
Add forked type checker from typescript loader
davidmpaz Jul 18, 2017
d0b36cd
Add tests for new ts type checker plugin
davidmpaz Jul 18, 2017
7d391b0
Call ensureLoaderPackagesExist ealier to avoid node error
davidmpaz Jul 19, 2017
9e5dff4
Add fork-ts-checker-webpack-plugin to packages.json
davidmpaz Jul 19, 2017
73ee341
Add return statement to allow chain calls
davidmpaz Jul 19, 2017
d74cfa9
Remmove browser request to reduce execution time
davidmpaz Jul 20, 2017
07c740a
Remove dependency check from WebpackConfig.js
davidmpaz Jul 21, 2017
4cbc25c
Move 'require' down after dependency check in loader
davidmpaz Jul 21, 2017
0c6c850
Increase timeout for forked functional test
davidmpaz Jul 21, 2017
666935d
Make timeout match default value and call done()
davidmpaz Jul 21, 2017
4fc0c11
Add test for public API
davidmpaz Jul 21, 2017
786a35f
Refactor plugin configuration
davidmpaz Jul 23, 2017
5f858d0
Update tests for forked ts type checking
davidmpaz Jul 23, 2017
b20c1a1
Change options parameters for a configuration callback
davidmpaz Jul 30, 2017
0613766
Update tests
davidmpaz Jul 30, 2017
2d669ed
Remove extra line in docs blocks
davidmpaz Jul 30, 2017
8adc7af
Improve english syntax
davidmpaz Jul 30, 2017
1edae71
Add forked check plugin to dev dependencies
davidmpaz Jul 30, 2017
d2cc270
Fix linting indentation
davidmpaz Jul 30, 2017
a8c6d1e
Update functional test
davidmpaz Jul 30, 2017
87efa63
Use const for required variables
davidmpaz Jul 30, 2017
494adf6
Fix linting errors
davidmpaz Jul 30, 2017
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -380,6 +380,23 @@ module.exports = {
return this;
},

/**
* Call this to enable forked type checking for TypeScript loader
* https://github.com/TypeStrong/ts-loader/blob/v2.3.0/README.md#faster-builds
*
* This is a build optimization API to reduce build times.
*
* @param {function} forkedTypeScriptTypesCheckOptionsCallback
* @return {exports}
*/
enableForkedTypeScriptTypesChecking(forkedTypeScriptTypesCheckOptionsCallback = () => {}) {
webpackConfig.enableForkedTypeScriptTypesChecking(
forkedTypeScriptTypesCheckOptionsCallback
);

return this;
},

/**
* If enabled, the Vue.js loader is enabled.
*
Expand Down
13 changes: 13 additions & 0 deletions lib/WebpackConfig.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ class WebpackConfig {
this.loaders = [];
this.useTypeScriptLoader = false;
this.tsConfigurationCallback = function() {};
this.useForkedTypeScriptTypeChecking = false;
this.forkedTypeScriptTypesCheckOptionsCallback = () => {};
}

getContext() {
Expand Down Expand Up @@ -238,6 +240,17 @@ class WebpackConfig {
this.tsConfigurationCallback = callback;
}

enableForkedTypeScriptTypesChecking(forkedTypeScriptTypesCheckOptionsCallback = () => {}) {

if (typeof forkedTypeScriptTypesCheckOptionsCallback !== 'function') {
throw new Error('Argument 1 to enableForkedTypeScriptTypesChecking() must be a callback function.');
}

this.useForkedTypeScriptTypeChecking = true;
this.forkedTypeScriptTypesCheckOptionsCallback =
forkedTypeScriptTypesCheckOptionsCallback;
}

enableVueLoader(vueLoaderOptionsCallback = () => {}) {
this.useVueLoader = true;

Expand Down
5 changes: 5 additions & 0 deletions lib/loader-features.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,11 @@ const loaderFeatures = {
packages: ['typescript', 'ts-loader'],
description: 'process TypeScript files'
},
forkedtypecheck: {
method: 'enableForkedTypeScriptTypesChecking()',
packages: ['typescript', 'ts-loader', 'fork-ts-checker-webpack-plugin'],
description: 'check TypeScript types in a separate process'
},
vue: {
method: 'enableVueLoader()',
// vue is needed so the end-user can do things
Expand Down
11 changes: 11 additions & 0 deletions lib/loaders/typescript.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,17 @@ module.exports = {
[config]
);

// fork-ts-checker-webpack-plugin integration
if (webpackConfig.useForkedTypeScriptTypeChecking) {
loaderFeatures.ensureLoaderPackagesExist('forkedtypecheck');
// force transpileOnly to speed up
config.transpileOnly = true;

// add forked ts types plugin to the stack
const forkedTypesPluginUtil = require('../plugins/forked-ts-types'); // eslint-disable-line
forkedTypesPluginUtil(webpackConfig);
}

// use ts alongside with babel
// @see https://github.com/TypeStrong/ts-loader/blob/master/README.md#babel
let loaders = babelLoader.getLoaders(webpackConfig);
Expand Down
29 changes: 29 additions & 0 deletions lib/plugins/forked-ts-types.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

'use strict';

const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin'); // eslint-disable-line

/**
* @param {WebpackConfig} webpackConfig
* @return {void}
*/
module.exports = function(webpackConfig) {
let config = {};

// allow for ts-loader config to be controlled
webpackConfig.forkedTypeScriptTypesCheckOptionsCallback.apply(
// use config as the this variable
config,
[config]
);

webpackConfig.addPlugin(new ForkTsCheckerWebpackPlugin(config));
};
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
"eslint": "^3.19.0",
"eslint-plugin-header": "^1.0.0",
"eslint-plugin-node": "^4.2.2",
"fork-ts-checker-webpack-plugin": "^0.2.7",
"http-server": "^0.9.0",
"less": "^2.7.2",
"less-loader": "^4.0.2",
Expand Down
19 changes: 19 additions & 0 deletions test/WebpackConfig.js
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,25 @@ describe('WebpackConfig object', () => {
});
});

describe('enableForkedTypeScriptTypesChecking', () => {
it('Calling method sets it', () => {
const config = createConfig();
config.enableTypeScriptLoader();
const testCallback = () => {};
config.enableForkedTypeScriptTypesChecking(testCallback);
expect(config.forkedTypeScriptTypesCheckOptionsCallback)
.to.equal(testCallback);
});

it('Calling with non-callback throws an error', () => {
const config = createConfig();

expect(() => {
config.enableForkedTypeScriptTypesChecking('FOO');
}).to.throw('must be a callback function');
});
});

describe('addPlugin', () => {
it('extends the current registered plugins', () => {
const config = createConfig();
Expand Down
38 changes: 29 additions & 9 deletions test/functional.js
Original file line number Diff line number Diff line change
Expand Up @@ -288,13 +288,13 @@ describe('Functional tests using webpack', function() {
'bg.483832e48e67e6a3b7f0ae064eadca51.css',
'manifest.json'
]
);
);

expect(path.join(config.outputPath, 'images')).to.be.a.directory()
.with.files([
'symfony_logo.ea1ca6f7.png'
]
);
);

webpackAssert.assertOutputFileContains(
'bg.483832e48e67e6a3b7f0ae064eadca51.css',
Expand All @@ -319,19 +319,19 @@ describe('Functional tests using webpack', function() {
'font.css',
'manifest.json'
]
);
);

expect(path.join(config.outputPath, 'images')).to.be.a.directory()
.with.files([
'symfony_logo.ea1ca6f7.png'
]
);
);

expect(path.join(config.outputPath, 'fonts')).to.be.a.directory()
.with.files([
'Roboto.9896f773.woff2'
]
);
);

webpackAssert.assertOutputFileContains(
'bg.css',
Expand Down Expand Up @@ -359,21 +359,21 @@ describe('Functional tests using webpack', function() {
'styles.css',
'manifest.json'
]
);
);

expect(path.join(config.outputPath, 'images')).to.be.a.directory()
.with.files([
'symfony_logo.ea1ca6f7.png',
'symfony_logo.f27119c2.png'
]
);
);

expect(path.join(config.outputPath, 'fonts')).to.be.a.directory()
.with.files([
'Roboto.9896f773.woff2',
'Roboto.3c37aa69.woff2'
]
);
);

webpackAssert.assertOutputFileContains(
'styles.css',
Expand Down Expand Up @@ -587,7 +587,7 @@ module.exports = {

fs.writeFileSync(
path.join(appDir, '.babelrc'),
`
`
{
"presets": [
["env", {
Expand Down Expand Up @@ -667,6 +667,26 @@ module.exports = {
});
});

it('TypeScript is compiled and type checking is done in a separate process!', (done) => {
this.timeout(8000);
setTimeout(done, 7000);

const config = createWebpackConfig('www/build', 'dev');
config.setPublicPath('/build');
config.addEntry('main', ['./js/render.ts', './js/index.ts']);
config.enableTypeScriptLoader();
// test should fail if `config.tsconfig` is not set up properly
config.enableForkedTypeScriptTypesChecking((config) => {
config.silent = true; // remove to get output on terminal
});

expect(function() {
testSetup.runWebpack(config, (webpackAssert) => {
done();
});
}).to.throw('wrong `tsconfig` path in fork plugin configuration (should be a relative or absolute path)');
});

it('The output directory is cleaned between builds', (done) => {
const config = createWebpackConfig('www/build', 'dev');
config.setPublicPath('/build');
Expand Down
9 changes: 9 additions & 0 deletions test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,15 @@ describe('Public API', () => {

});

describe('enableForkedTypeScriptTypesChecking', () => {

it('must return the API object', () => {
const returnedValue = api.enableForkedTypeScriptTypesChecking();
expect(returnedValue).to.equal(api);
});

});

describe('enableVueLoader', () => {

it('must return the API object', () => {
Expand Down
41 changes: 41 additions & 0 deletions test/plugins/forked-ts-types.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

'use strict';

const expect = require('chai').expect;
const WebpackConfig = require('../../lib/WebpackConfig');
const RuntimeConfig = require('../../lib/config/RuntimeConfig');
const tsLoader = require('../../lib/loaders/typescript');
const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');

function createConfig() {
const runtimeConfig = new RuntimeConfig();
runtimeConfig.context = __dirname;
runtimeConfig.babelRcFileExists = false;

return new WebpackConfig(runtimeConfig);
}

describe('plugins/forkedtypecheck', () => {
it('getPlugins() basic usage', () => {
const config = createConfig();
config.enableTypeScriptLoader();
config.enableForkedTypeScriptTypesChecking();

expect(config.plugins).to.have.lengthOf(0);
const tsTypeChecker = require('../../lib/plugins/forked-ts-types');
tsTypeChecker(config);
expect(config.plugins).to.have.lengthOf(1);
expect(config.plugins[0]).to.be.an.instanceof(ForkTsCheckerWebpackPlugin);
// after enabling plugin, check typescript loader has right config
const actualLoaders = tsLoader.getLoaders(config);
expect(actualLoaders[1].options.transpileOnly).to.be.true;
});
});
Loading