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

fix: support evaluating TypeScript files by default. fixes #27 #283

Merged
merged 1 commit into from
Dec 19, 2018
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions src/__fixtures__/sample-typescript.tsx
@@ -0,0 +1 @@
export default 27;
13 changes: 13 additions & 0 deletions src/__tests__/module.test.js
Expand Up @@ -61,6 +61,19 @@ it('imports JS files', () => {
expect(mod.exports.result).toBe('The answer is 42');
});

it('imports TypeScript files', () => {
const mod = new Module(path.resolve(__dirname, '../__fixtures__/test.ts'));

mod.transform = transform;
mod.evaluate(dedent`
import answer from './sample-typescript';

export const result = 'The answer is ' + answer;
`);

expect(mod.exports.result).toBe('The answer is 27');
});

it('imports JSON files', () => {
const mod = new Module(path.resolve(__dirname, '../__fixtures__/test.js'));

Expand Down
35 changes: 31 additions & 4 deletions src/babel/module.js
Expand Up @@ -32,6 +32,7 @@ class Module {
require: (id: string) => any;
exports: any;

extensions: string[];
transform: ?(text: string) => { code: string }
*/

Expand All @@ -58,10 +59,35 @@ class Module {
this.require.resolve = this.resolve.bind(this);
this.require.ensure = NOOP;
this.require.cache = cache;

// We support following extensions by default
this.extensions = ['.json', '.js', '.ts', '.tsx'];
Copy link
Member

Choose a reason for hiding this comment

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

add .jsx as well? I'm cool with not adding that and forcing others to just use .js though :D

Copy link
Member Author

Choose a reason for hiding this comment

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

death to .jsx

Copy link
Member

Choose a reason for hiding this comment

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

Should kill .tsx as well then XD

Copy link
Member Author

Choose a reason for hiding this comment

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

@thymikee I would if I could. But due to syntax ambiguity with deprecated typecast syntax, TypeScript relies on the .tsx extension to understand JSX!

Copy link
Member

Choose a reason for hiding this comment

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

What a shame. Flow doesn't have these issues :D Hopefully they can get rid of deprecations soon 🙂

}

resolve(id /* : string */) {
return NativeModule._resolveFilename(id, this);
const extensions = NativeModule._extensions;
const added = [];

try {
// Check for supported extensions
this.extensions.forEach(ext => {
if (ext in extensions) {
return;
}

// When an extension is not supported, add it
// And keep track of it to clean it up after resolving
// Use noop for the tranform function since we handle it
extensions[ext] = NOOP;
added.push(ext);
});

// Resolve the module using node's resolve algorithm
return NativeModule._resolveFilename(id, this);
} finally {
// Cleanup the extensions we added to restore previous behaviour
added.forEach(ext => delete extensions[ext]);
}
}

require(id /* : string */) {
Expand All @@ -86,15 +112,16 @@ class Module {
// we would end up in infinite loop with cyclic dependencies
cache[filename] = m;

if (/\.(js|json)$/.test(filename)) {
// For JS/JSON files, we need to read the file first
if (this.extensions.includes(path.extname(filename))) {
// To evaluate the file, we need to read it first
const code = fs.readFileSync(filename, 'utf-8');

if (/\.json$/.test(filename)) {
// For JSON files, parse it to a JS object similar to Node
m.exports = JSON.parse(code);
} else {
// For JS files, evaluate the module
// For JS/TS files, evaluate the module
// The module will be transpiled using provided transform
m.evaluate(code);
}
} else {
Expand Down
1 change: 1 addition & 0 deletions tslint.json
@@ -1,6 +1,7 @@
{
"extends": "dtslint/dtslint.json",
"rules": {
"file-name-casing": false,
"interface-over-type-literal": false,
"strict-export-declare-modifiers": false
}
Expand Down