Skip to content
This repository was archived by the owner on Dec 1, 2019. It is now read-only.

Commit d7a8a64

Browse files
committed
feat(*): allowJs works (wip)
1 parent 7b86044 commit d7a8a64

File tree

13 files changed

+104
-94
lines changed

13 files changed

+104
-94
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,4 @@ tscommand
66
npm-debug.log
77
.awcache
88
test/output
9+
src/test/output

src/deps.ts

+28-5
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,38 @@ export interface IExternals {
2121
[key: string]: string;
2222
}
2323

24-
export function createResolver(externals: IExternals, webpackResolver: any): IResolver {
24+
export type Exclude = string[];
25+
26+
export function createResolver(
27+
externals: IExternals,
28+
exclude: Exclude,
29+
webpackResolver: any
30+
): IResolver {
2531
let resolver: IResolver = promisify(webpackResolver) as any;
2632

2733
function resolve(base: string, dep: string): Promise<string> {
28-
if (externals && externals.hasOwnProperty(dep)) {
34+
let inWebpackExternals = externals && externals.hasOwnProperty(dep);
35+
let inTypeScriptExclude = false;
36+
37+
if ((inWebpackExternals || inTypeScriptExclude)) {
2938
return Promise.resolve<string>('%%ignore');
3039
} else {
31-
return resolver(base, dep);
40+
return resolver(base, dep).then(resultPath => {
41+
// ignore excluded javascript
42+
if (!resultPath.match(/.tsx?$/)) {
43+
let matchedExcludes = exclude.filter((excl) => {
44+
return resultPath.indexOf(excl) !== -1;
45+
});
46+
47+
if (matchedExcludes.length > 0) {
48+
return '%%ignore';
49+
} else {
50+
return resultPath;
51+
}
52+
} else {
53+
return resultPath;
54+
}
55+
});
3256
}
3357
}
3458

@@ -100,7 +124,7 @@ export class FileAnalyzer {
100124
this.dependencies.addTypeDeclaration(importPath);
101125
tasks.push(this.checkDependencies(resolver, importPath));
102126
}
103-
} else if (isRequiredJs) {
127+
} else if (isRequiredJs && !this.state.options.allowJs) {
104128
continue;
105129
} else {
106130
this.dependencies.addDependency(fileName, importPath);
@@ -139,7 +163,6 @@ export class FileAnalyzer {
139163
});
140164

141165
let resolvedImports = await Promise.all(task);
142-
143166
return resolvedImports.filter(Boolean);
144167
}
145168

src/host.ts

+11
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ export interface ICompilerOptions extends ts.CompilerOptions {
3838
reEmitDependentFiles?: boolean;
3939
tsconfig?: string;
4040
useWebpackText?: boolean;
41+
exclude?: string[];
4142
externals?: any;
4243
doTypeCheck?: boolean;
4344
forkChecker?: boolean;
@@ -99,6 +100,16 @@ export class Host implements ts.LanguageServiceHost {
99100
let file = this.state.getFile(fileName);
100101
if (!file) {
101102
try {
103+
// ignore excluded javascript
104+
if (!fileName.match(/\.tsx?$|package[.]json?$/)) {
105+
let matchedExcludes = this.state.options.exclude.filter((excl) => {
106+
return fileName.indexOf(excl) !== -1;
107+
});
108+
if (matchedExcludes.length > 0) {
109+
return;
110+
}
111+
}
112+
102113
let text = this.state.readFileSync(fileName);
103114
file = {
104115
version: 0,

src/index.ts

+6-1
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,12 @@ async function compiler(webpack: IWebPack, text: string): Promise<void> {
4444
let callback = webpack.async();
4545
let fileName = state.normalizePath(webpack.resourcePath);
4646

47-
let resolver = createResolver(webpack._compiler.options.externals, webpack.resolve);
47+
let resolver = createResolver(
48+
webpack._compiler.options.externals,
49+
state.options.exclude || [],
50+
webpack.resolve
51+
);
52+
4853
let depsInjector = {
4954
add: (depFileName) => webpack.addDependency(depFileName),
5055
clear: webpack.clearDependencies.bind(webpack)

src/instance.ts

+9-3
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,7 @@ export function ensureInstance(webpack: IWebPack, options: ICompilerOptions, ins
167167
if (configFile.compilerOptions) {
168168
_.extend(options, configFile.compilerOptions);
169169
_.extend(options, (configFile as any).awesomeTypescriptLoaderOptions);
170+
options.exclude = configFile.exclude || [];
170171
tsFiles = configFile.files;
171172
}
172173
}
@@ -179,10 +180,11 @@ export function ensureInstance(webpack: IWebPack, options: ICompilerOptions, ins
179180
sourceMap: true,
180181
verbose: false,
181182
noLib: false,
183+
suppressOutputPathCheck: true,
182184
sourceRoot: process.cwd()
183185
});
184186

185-
options = _.omit(options, 'outDir', 'files', 'exclude') as any;
187+
options = _.omit(options, 'outDir', 'files') as any;
186188
options.externals.push.apply(options.externals, tsFiles);
187189

188190
let babelImpl: any;
@@ -263,9 +265,13 @@ export function ensureInstance(webpack: IWebPack, options: ICompilerOptions, ins
263265
function setupWatchRun(compiler, instanceName: string) {
264266
compiler.plugin('watch-run', async function (watching, callback) {
265267
let compiler: ICompiler = watching.compiler;
266-
let resolver = createResolver(compiler.options.externals, watching.compiler.resolvers.normal.resolve);
267268
let instance = resolveInstance(watching.compiler, instanceName);
268269
let state = instance.tsState;
270+
let resolver = createResolver(
271+
compiler.options.externals,
272+
state.options.exclude || [],
273+
watching.compiler.resolvers.normal.resolve
274+
);
269275
let mtimes = watching.compiler.watchFileSystem.watcher.mtimes;
270276
let changedFiles = Object.keys(mtimes);
271277

@@ -275,7 +281,7 @@ function setupWatchRun(compiler, instanceName: string) {
275281

276282
try {
277283
let tasks = changedFiles.map(async function(changedFile) {
278-
if (/\.ts$|\.d\.ts|\.tsx$/.test(changedFile)) {
284+
if (/\.ts$|\.d\.ts$|\.tsx$|\.js$|\.jsx$/.test(changedFile)) {
279285
await state.readFileAndUpdate(changedFile);
280286
await state.fileAnalyzer.checkDependencies(resolver, changedFile);
281287
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
/**
2+
* @param {number} a - a
3+
* @param {number} b - b
4+
* @return {number}
5+
*/
6+
module.exports = function mul(a, b) {
7+
return a * b;
8+
}

src/test/fixtures/salsa/index.js

-17
This file was deleted.

src/test/fixtures/salsa/index.ts

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import { sum } from './lib';
2+
import { mul } from './exclude/ignored';
3+
4+
sum('asdf', /asdf/);
5+
6+
// should be any
7+
mul('asdf', /asdf/);

src/test/fixtures/salsa/lib.js

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
/**
2+
* @param {number} a - a
3+
* @param {number} b - b
4+
* @return {number}
5+
*/
6+
export function sum(a, b) {
7+
return a + b;
8+
}

src/test/fixtures/salsa/tsconfig.json

+2-5
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,10 @@
22
"compilerOptions": {
33
"target": "es5",
44
"declaration": false,
5-
"noImplicitAny": false,
6-
"noEmitOnError": false,
7-
"allowNonTsExtensions": true,
8-
"allowJs": true,
9-
"noLib": true
5+
"allowJs": true
106
},
117
"exclude": [
8+
"exclude",
129
"node_modules",
1310
"bower_components"
1411
]

src/test/output/main.js

-55
This file was deleted.

src/test/salsa.ts

+9-6
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,21 @@
11
import {
2-
cleanAndCompile, expect, readOutputFile,
3-
fixturePath, readFixture, expectSource, createConfig
2+
cleanAndCompile, expect,
3+
fixturePath, createConfig
44
} from './utils';
55

66
describe('salsa test', function() {
7-
xit('should compile js file', async function() {
7+
it('should compile js file', async function() {
88
let config = {
9-
entry: fixturePath(['salsa', 'index.js'])
9+
entry: fixturePath(['salsa', 'index.ts'])
1010
};
1111

1212
let tsconfig = fixturePath(['salsa', 'tsconfig.json']);
1313
let loaderParams = `&tsconfig=${tsconfig}`;
14+
let exclude = [ /exclude/ ];
1415

15-
let stats = await cleanAndCompile(createConfig(config, { loaderParams }));
16-
expect(stats.compilation.errors.length).eq(1);
16+
let stats = await cleanAndCompile(createConfig(config, { loaderParams, exclude }));
17+
expect(stats.compilation.errors.length).eq(2);
18+
expect(stats.compilation.errors[0].toString()).include('Cannot find module');
19+
expect(stats.compilation.errors[1].toString()).include(`Argument of type 'string'`);
1720
});
1821
});

src/test/utils.ts

+15-2
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,14 @@ export interface ConfigOptions {
2525
loaderParams?: string;
2626
watch?: boolean;
2727
forkChecker?: boolean;
28+
include?: (string | RegExp)[];
29+
exclude?: (string | RegExp)[];
2830
}
2931

3032
let defaultOptions: ConfigOptions = {
3133
loaderParams: '',
3234
watch: false,
33-
forkChecker: false
35+
forkChecker: false,
3436
};
3537

3638
export function createConfig(conf, _options: ConfigOptions = defaultOptions) {
@@ -41,17 +43,28 @@ export function createConfig(conf, _options: ConfigOptions = defaultOptions) {
4143
path: defaultOutputDir,
4244
filename: '[name].js'
4345
},
46+
resolve: {
47+
extensions: ['', '.ts', '.tsx', '.js', '.jsx'],
48+
},
4449
module: {
4550
loaders: [
4651
{
4752
test: /\.(tsx?|jsx?)/,
48-
loader: loaderDir + '?doTypeCheck&target=es6' + options.loaderParams,
53+
loader: loaderDir + '?target=es5' + options.loaderParams,
4954
},
5055
],
5156
},
5257
plugins: []
5358
};
5459

60+
if (options.include) {
61+
(defaultConfig.module.loaders[0] as any).include = options.include;
62+
}
63+
64+
if (options.exclude) {
65+
(defaultConfig.module.loaders[0] as any).exclude = options.exclude;
66+
}
67+
5568
if (options.watch) {
5669
defaultConfig.watch = true;
5770
}

0 commit comments

Comments
 (0)