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

Fixes #336. Add happypack compatibility mode #547

Merged
merged 6 commits into from
May 21, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
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") } }