Skip to content

Commit

Permalink
Fixes #336. Add happypack compatibility mode (#547)
Browse files Browse the repository at this point in the history
* Fixes #336. Add happypack compatibility mode
* Update README.md
* Made happypack a devDependency - In the longer term move this into test itself. Need to rejig test framework a little first.
* Don't call registerWebpackErrors in happyPackMode
  • Loading branch information
Artem Kozlov authored and johnnyreilly committed May 21, 2017
1 parent 19c7a6f commit 70f0595
Show file tree
Hide file tree
Showing 16 changed files with 158 additions and 13 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,5 @@ npm-debug.log
!/test/**/expectedOutput-*/**
/**/node_modules
/**/dist
/**/.happypack
!build.js
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,10 @@ Advanced option to force files to go through different instances of the
TypeScript compiler. Can be used to force segregation between different parts
of your code.

##### happyPackMode *(boolean) (default=false)*

Enables [`happypack`](https://github.com/amireh/happypack) compatibility mode. This implicitly sets `*transpileOnly*` to `true`. **WARNING!** Some errors will be silently ignored in `happypack` mode (`tsconfig.json` parsing errors, dependency resolution errors, etc.).

#### entryFileIsJs *(boolean) (default=false)*

To be used in concert with the `allowJs` compiler option. If your entry file is JS then you'll need to set this option to true. Please note that this is rather unusual and will generally not be necessary when using `allowJs`.
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
"escape-string-regexp": "^1.0.3",
"fs-extra": "^3.0.0",
"glob": "^7.1.1",
"happypack": "^3.1.0",
"html-webpack-plugin": "^2.17.0",
"jasmine-core": "^2.5.2",
"karma": "^1.3.0",
Expand Down
26 changes: 18 additions & 8 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,13 @@ function loader(this: interfaces.Webpack, contents: string) {

const { sourceMap, output } = makeSourceMap(sourceMapText, outputText, filePath, contents, this);

// Make sure webpack is aware that even though the emitted JavaScript may be the same as
// a previously cached version the TypeScript may be different and therefore should be
// treated as new
this._module.meta.tsLoaderFileVersion = fileVersion;
// _module.meta is not available inside happypack
if (!options.happyPackMode) {
// Make sure webpack is aware that even though the emitted JavaScript may be the same as
// a previously cached version the TypeScript may be different and therefore should be
// treated as new
this._module.meta.tsLoaderFileVersion = fileVersion;
}

callback(null, output, sourceMap);
}
Expand Down Expand Up @@ -82,12 +85,16 @@ function getLoaderOptions(loader: interfaces.Webpack) {
compilerOptions: {},
appendTsSuffixTo: [],
entryFileIsJs: false,
happyPackMode: false,
}, configFileOptions, queryOptions);

options.ignoreDiagnostics = utils.arrify(options.ignoreDiagnostics).map(Number);
options.logLevel = options.logLevel.toUpperCase();
options.instance = instanceName;

// happypack can be used only together with transpileOnly mode
options.transpileOnly = options.happyPackMode ? true : options.transpileOnly;

loaderOptionsCache[instanceName] = options;

return options;
Expand Down Expand Up @@ -182,10 +189,13 @@ function getTranspilationEmit(
fileName,
});

utils.registerWebpackErrors(
loader._module.errors,
utils.formatErrors(diagnostics, instance.loaderOptions, instance.compiler, { module: loader._module })
);
// _module.errors is not available inside happypack - see https://github.com/TypeStrong/ts-loader/issues/336
if (!instance.loaderOptions.happyPackMode) {
utils.registerWebpackErrors(
loader._module.errors,
utils.formatErrors(diagnostics, instance.loaderOptions, instance.compiler, { module: loader._module })
);
}

return { outputText, sourceMapText };
}
Expand Down
13 changes: 8 additions & 5 deletions src/instances.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ export function getTypeScriptInstance(

const configParseResult = config.getConfigParseResult(compiler, configFile, configFilePath);

if (configParseResult.errors.length) {
if (configParseResult.errors.length && !loaderOptions.happyPackMode) {
utils.registerWebpackErrors(
loader._module.errors,
utils.formatErrors(configParseResult.errors, loaderOptions, compiler, { file: configFilePath }));
Expand All @@ -64,10 +64,13 @@ export function getTypeScriptInstance(
const program = compiler.createProgram([], compilerOptions);
const diagnostics = program.getOptionsDiagnostics();

utils.registerWebpackErrors(
loader._module.errors,
utils.formatErrors(diagnostics, loaderOptions, compiler, {file: configFilePath || 'tsconfig.json'}));

// happypack does not have _module.errors - see https://github.com/TypeStrong/ts-loader/issues/336
if (!loaderOptions.happyPackMode) {
utils.registerWebpackErrors(
loader._module.errors,
utils.formatErrors(diagnostics, loaderOptions, compiler, {file: configFilePath || 'tsconfig.json'}));
}

return { instance: instances[loaderOptions.instance] = { compiler, compilerOptions, loaderOptions, files, dependencyGraph: {}, reverseDependencyGraph: {} }};
}

Expand Down
1 change: 1 addition & 0 deletions src/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,7 @@ export interface LoaderOptions {
compilerOptions: typescript.CompilerOptions;
appendTsSuffixTo: RegExp[];
entryFileIsJs: boolean;
happyPackMode: boolean;
}

export interface TSFile {
Expand Down
53 changes: 53 additions & 0 deletions test/execution-tests/basic-happypack/karma.conf.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/* eslint-disable no-var, strict */
'use strict';
var path = require('path');
var webpack = require('webpack');
var webpackConfig = require('./webpack.config.js');

module.exports = function(config) {
config.set({
browsers: [ 'PhantomJS' ],

files: [
// This loads all the tests
'main.js'
],

port: 9876,

frameworks: [ 'jasmine' ],

logLevel: config.LOG_INFO, //config.LOG_DEBUG

preprocessors: {
'main.js': [ 'webpack', 'sourcemap' ]
},

webpack: {
devtool: 'inline-source-map',
module: webpackConfig.module,
resolve: webpackConfig.resolve,
plugins: webpackConfig.plugins,

// for test harness purposes only, you would not need this in a normal project
resolveLoader: webpackConfig.resolveLoader
},

webpackMiddleware: {
quiet: true,
stats: {
colors: true
}
},

// reporter options
mochaReporter: {
colors: {
success: 'bgGreen',
info: 'cyan',
warning: 'bgBlue',
error: 'bgRed'
}
}
});
};
7 changes: 7 additions & 0 deletions test/execution-tests/basic-happypack/lib/externalLib.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
declare module externalLib {
export function doSomething(arg: any): void;
}

declare module 'externalLib' {
export = externalLib
}
3 changes: 3 additions & 0 deletions test/execution-tests/basic-happypack/lib/externalLib.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module.exports = {
doSomething: function() { }
}
2 changes: 2 additions & 0 deletions test/execution-tests/basic-happypack/main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
const testsContext = require.context('./', true, /\.tests\.ts(x?)$/);
testsContext.keys().forEach(testsContext);
3 changes: 3 additions & 0 deletions test/execution-tests/basic-happypack/src/app.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import submodule = require('./submodule/submodule');
import externalLib = require('externalLib');
externalLib.doSomething(submodule);
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import externalLib = require('externalLib');

externalLib.doSomething("");
var message = "Hello from submodule"
export = message
12 changes: 12 additions & 0 deletions test/execution-tests/basic-happypack/test/app.tests.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import submodule = require('../src/submodule/submodule');
import externalLib = require('externalLib');

describe("app", () => {
it("externalLib can be called", () => {
expect(externalLib.doSomething(submodule)).toBeUndefined();
});

it("submodule return value can be reached", () => {
expect(submodule).toBe("Hello from submodule");
});
});
5 changes: 5 additions & 0 deletions test/execution-tests/basic-happypack/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"compilerOptions": {

}
}
7 changes: 7 additions & 0 deletions test/execution-tests/basic-happypack/typings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"name": "simple",
"version": false,
"globalDependencies": {
"jasmine": "github:DefinitelyTyped/DefinitelyTyped/jasmine/jasmine.d.ts#fe563dff3428bac1260d1794e2c2ecf8f097535a"
}
}
28 changes: 28 additions & 0 deletions test/execution-tests/basic-happypack/webpack.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
var path = require('path');
var HappyPack = require('happypack');

module.exports = {
entry: './src/app.ts',
output: {
filename: 'bundle.js'
},
resolve: {
alias: { externalLib: path.join(__dirname, "./lib/externalLib.js") },
extensions: ['.ts', '.js']
},
module: {
rules: [
{ test: /\.ts$/, loader: 'happypack/loader?id=ts'}
]
},
plugins: [
new HappyPack({
id: 'ts',
threads : 2,
loaders: [ "ts-loader?" + JSON.stringify({happyPackMode: true}) ]
})
]
};

// for test harness purposes only, you would not need this in a normal project
module.exports.resolveLoader = { alias: { 'ts-loader': require('path').join(__dirname, "../../../index.js") } }

0 comments on commit 70f0595

Please sign in to comment.