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

Provide TypeScript compilation support when using ember-cli-typescript@4 or higher. #314

Merged
merged 27 commits into from
Feb 5, 2020
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
9e5baac
Include decorator and class field plugins after TypeScript, if present
dfreeman Dec 12, 2019
f602be4
feat: add TypeScript tranform when e-c-ts >= 4.0.0-alpha
jamescdavis Dec 19, 2019
e2680b1
tests: add tests for _addTypeScriptPlugins()
jamescdavis Dec 19, 2019
55ac0b2
tests: add (failing) test for _getExtensions
jamescdavis Dec 19, 2019
7f81c47
fix: don't add ts to user-configured extensions
jamescdavis Dec 19, 2019
5a1f5a8
refactor: simplify extension determination
jamescdavis Dec 19, 2019
e88eeb9
feat: added caching of ember-cli-typescript version check
jamescdavis Dec 19, 2019
b05c974
fix: conditionally apply class feature ordering restrictions
jamescdavis Dec 19, 2019
134b0a4
tests: test conditional class feature ordering restrictions
jamescdavis Dec 19, 2019
2e79c2f
fix: don't conditionally add optional chaining and nullish coalescing
jamescdavis Dec 19, 2019
14e7590
refactor: get e-c-ts version from parent.addons
jamescdavis Dec 20, 2019
24b8d09
tests: add test for _shouldHandleTypeScript
jamescdavis Dec 20, 2019
7c6db15
feat: add flag for manual override
jamescdavis Dec 20, 2019
304e67a
Merge branch 'master' into add_typescript_transform_plugin
jamescdavis Dec 20, 2019
ac58290
refactor: only enforce TS transform else case
jamescdavis Dec 30, 2019
21de796
feat: handle ts (in addition to js) by default
jamescdavis Dec 30, 2019
802323f
chore: s/\t/ /
jamescdavis Jan 8, 2020
5d7a817
chore: add ember-cli-typescript version to comment
jamescdavis Jan 8, 2020
5fb2aa0
docs: document enableTypeScriptTransforms
jamescdavis Jan 8, 2020
6393260
Revert "feat: handle ts (in addition to js) by default"
jamescdavis Jan 10, 2020
9bf6424
fix: e-c-ts was released as 4.0.0-alpha.1
jamescdavis Jan 18, 2020
f6adfe1
fix: don't emit modules for .d.ts files
dfreeman Jan 20, 2020
bcbddff
Merge pull request #1 from dfreeman/exclude-ts-declarations
jamescdavis Jan 20, 2020
11df8e5
Merge branch 'master' into add_typescript_transform_plugin
jamescdavis Jan 24, 2020
22480f1
Merge branch 'master' into add_typescript_transform_plugin
jamescdavis Jan 27, 2020
d0db857
chore: upgrade to latest @babel packages
jamescdavis Jan 27, 2020
4ab55d1
refactor: don't explicitly add optional-chaining/nullish coalescing
jamescdavis Jan 27, 2020
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
108 changes: 100 additions & 8 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -254,14 +254,16 @@ module.exports = {
},

_getExtensions(config) {
let shouldHandleTypeScript = this._shouldHandleTypeScript();
let emberCLIBabelConfig = config['ember-cli-babel'] || {};
return emberCLIBabelConfig.extensions || ['js'];
return emberCLIBabelConfig.extensions || (shouldHandleTypeScript ? ['js', 'ts'] : ['js']);
rwjblue marked this conversation as resolved.
Show resolved Hide resolved
},

_getBabelOptions(config) {
let addonProvidedConfig = this._getAddonProvidedConfig(config);
let shouldCompileModules = this._shouldCompileModules(config);
let shouldIncludeHelpers = this._shouldIncludeHelpers(config);
let shouldHandleTypeScript = this._shouldHandleTypeScript();
let shouldIncludeDecoratorPlugins = this._shouldIncludeDecoratorPlugins(config);

let emberCLIBabelConfig = config['ember-cli-babel'];
Expand Down Expand Up @@ -292,6 +294,10 @@ module.exports = {
let userPlugins = addonProvidedConfig.plugins;
let userPostTransformPlugins = addonProvidedConfig.postTransformPlugins;

if (shouldHandleTypeScript) {
userPlugins = this._addTypeScriptPlugins(userPlugins.slice(), addonProvidedConfig.options);
}

if (shouldIncludeDecoratorPlugins) {
userPlugins = this._addDecoratorPlugins(userPlugins.slice(), addonProvidedConfig.options);
}
Expand Down Expand Up @@ -320,6 +326,93 @@ module.exports = {
return options;
},

_shouldHandleTypeScript() {
if (this._cachedShouldHandleTypescript === undefined) {
// TODO: this doesn't account for things like in-repo addons and other
// weird inclusion structures
let checker = new VersionChecker(this.parent).for('ember-cli-typescript', 'npm');
rwjblue marked this conversation as resolved.
Show resolved Hide resolved

this._cachedShouldHandleTypescript = checker.gte('4.0.0-alpha.0');
}

return this._cachedShouldHandleTypescript;
},

_buildClassFeaturePluginConstraints(constraints) {
// With older versions of ember-cli-typescript, class feature plugins like
rwjblue marked this conversation as resolved.
Show resolved Hide resolved
// @babel/plugin-proposal-class-properties were run before the TS transform.
// With more recent language features like `declare` field modifiers, Babel
// now has assertions requiring that the TS transform runs first, so if we
// know we're responsible for setting that transform up, we follow those rules.
if (this._shouldHandleTypeScript()) {
constraints.after = constraints.after || [];
rwjblue marked this conversation as resolved.
Show resolved Hide resolved
constraints.after.push('@babel/plugin-transform-typescript');
} else {
constraints.before = constraints.before || [];
constraints.before.push('@babel/plugin-transform-typescript');
}

return constraints;
},

_addTypeScriptPlugins(plugins) {
const { hasPlugin, addPlugin } = require('ember-cli-babel-plugin-helpers');

if (hasPlugin(plugins, '@babel/plugin-proposal-optional-chaining')) {
if (this.parent === this.project) {
this.project.ui.writeWarnLine(`${
this._parentName()
} has added the optional chaining plugin to its build, but ember-cli-babel provides this by default now when ember-cli-typescript >= 4.0 and typescript >= 3.7 are installed! You can remove the transform, or the addon that provided it.`);
Copy link
Member

Choose a reason for hiding this comment

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

Just to double check, this is added by default because TypeScript requires it? Also, how do you know that typescript >= 3.7 is being used (does e-c-ts bring a minimum of typescript@3.7?)?

Copy link
Member

Choose a reason for hiding this comment

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

Side note, we may want to make a more official policy to include things like this in the future (e.g. "stage-3 proposals are added by default"), not sure but that would probably require an RFC.

What do you think @pzuraq?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, this is because these features are part of TS >= 3.7. The reason these have to be added unconditionally is because we don't know the TypeScript version an addon might have used.

}
} else {
addPlugin(
plugins,
[
require.resolve('@babel/plugin-proposal-optional-chaining'),
]
);
}

if (hasPlugin(plugins, '@babel/plugin-proposal-nullish-coalescing-operator')) {
if (this.parent === this.project) {
this.project.ui.writeWarnLine(`${
this._parentName()
} has added the nullish coalescing operator plugin to its build, but ember-cli-babel provides this by default now when ember-cli-typescript >= 4.0 and typescript >= 3.7 are installed! You can remove the transform, or the addon that provided it.`);
}
} else {
addPlugin(
plugins,
[
require.resolve('@babel/plugin-proposal-nullish-coalescing-operator'),
]
);
}

if (hasPlugin(plugins, '@babel/plugin-transform-typescript')) {
if (this.parent === this.project) {
this.project.ui.writeWarnLine(`${
this._parentName()
} has added the TypeScript transform plugin to its build, but ember-cli-babel provides this by default now when ember-cli-typescript >= 4.0 is installed! You can remove the transform, or the addon that provided it.`);
}
} else {
addPlugin(
plugins,
[
require.resolve('@babel/plugin-transform-typescript'),
{ allowDeclareFields: true },
],
{
before: [
'@babel/plugin-proposal-class-properties',
'@babel/plugin-proposal-private-methods',
'@babel/plugin-proposal-decorators',
]
}
);
}
return plugins;
},

_shouldIncludeDecoratorPlugins(config) {
let customOptions = config['ember-cli-babel'] || {};

Expand All @@ -339,9 +432,9 @@ module.exports = {
addPlugin(
plugins,
[require.resolve('@babel/plugin-proposal-decorators'), { legacy: true }],
{
before: ['@babel/plugin-proposal-class-properties', '@babel/plugin-transform-typescript']
}
this._buildClassFeaturePluginConstraints({
before: ['@babel/plugin-proposal-class-properties']
})
);
}

Expand All @@ -356,10 +449,9 @@ module.exports = {
addPlugin(
plugins,
[require.resolve('@babel/plugin-proposal-class-properties'), { loose: options.loose || false }],
{
after: ['@babel/plugin-proposal-decorators'],
before: ['@babel/plugin-transform-typescript']
}
this._buildClassFeaturePluginConstraints({
after: ['@babel/plugin-proposal-decorators']
})
);
}

Expand Down
76 changes: 76 additions & 0 deletions node-tests/addon-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -746,6 +746,51 @@ describe('ember-cli-babel', function() {
});
});

describe('_addTypeScriptPlugins', function() {
it('should add TypeScript, optional chaining, and nullish coalescing operator plugins', function() {
expect(this.addon._addTypeScriptPlugins([], {}).length).to.equal(3, 'plugins added correctly');
});

it('should warn and not add the TypeScript plugin if already added', function() {
this.addon.project.ui = {
writeWarnLine(message) {
expect(message).to.match(/has added the TypeScript transform plugin to its build/);
}
};

expect(
this.addon._addTypeScriptPlugins([
['@babel/plugin-transform-typescript']
],
{}
).length).to.equal(3, 'plugin was not added');
});

it('should warn and not add optional chaining if already added', function() {
this.addon.project.ui = {
writeWarnLine(message) {
expect(message).to.match(/has added the optional chaining plugin to its build/);
}
};

expect(this.addon._addTypeScriptPlugins([
['@babel/plugin-proposal-optional-chaining']
], {}).length).to.equal(3, 'plugin was not added');
});

it('should warn and not add nullish coalescing operator if already added', function() {
this.addon.project.ui = {
writeWarnLine(message) {
expect(message).to.match(/has added the nullish coalescing operator plugin to its build/);
}
};

expect(this.addon._addTypeScriptPlugins([
['@babel/plugin-proposal-nullish-coalescing-operator']
], {}).length).to.equal(3, 'plugin was not added');
});
});

describe('_addDecoratorPlugins', function() {
it('should include babel transforms by default', function() {
expect(this.addon._addDecoratorPlugins([], {}).length).to.equal(2, 'plugins added correctly');
Expand Down Expand Up @@ -792,6 +837,20 @@ describe('ember-cli-babel', function() {

expect(loosePlugins[1][1].loose).to.equal(true, 'loose setting added correctly');
});

it('should include class fields and decorators after typescript if handling typescript', function() {
this.addon._shouldHandleTypeScript = function() { return true; }
let plugins = this.addon._addDecoratorPlugins(['@babel/plugin-transform-typescript'], {});
expect(plugins[0]).to.equal('@babel/plugin-transform-typescript', 'typescript still first');
expect(plugins.length).to.equal(3, 'class fields and decorators added');
});

it('should include class fields and decorators before typescript if not handling typescript', function() {
this.addon._shouldHandleTypeScript = function() { return false; }
let plugins = this.addon._addDecoratorPlugins(['@babel/plugin-transform-typescript'], {});
expect(plugins.length).to.equal(3, 'class fields and decorators added');
expect(plugins[2]).to.equal('@babel/plugin-transform-typescript', 'typescript is now last');
});
});

describe('_shouldIncludeHelpers()', function() {
Expand Down Expand Up @@ -973,6 +1032,23 @@ describe('ember-cli-babel', function() {
});
});

describe('_getExtensions', function() {
it('defaults to js only', function() {
expect(this.addon._getExtensions({})).to.have.members(['js']);
});
it('adds ts automatically', function() {
this.addon._shouldHandleTypeScript = function() { return true; }
expect(this.addon._getExtensions({})).to.have.members(['js', 'ts']);
});
it('respects user-configured extensions', function() {
expect(this.addon._getExtensions({ 'ember-cli-babel': { extensions: ['coffee'] } })).to.have.members(['coffee']);
});
it('respects user-configured extensions even when adding TS plugin', function() {
this.addon._shouldHandleTypeScript = function() { return true; }
expect(this.addon._getExtensions({ 'ember-cli-babel': { extensions: ['coffee'] } })).to.have.members(['coffee']);
});
});

describe('buildBabelOptions', function() {
this.timeout(0);

Expand Down
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,11 @@
"@babel/core": "^7.7.0",
"@babel/plugin-proposal-class-properties": "^7.7.0",
"@babel/plugin-proposal-decorators": "^7.7.0",
"@babel/plugin-proposal-nullish-coalescing-operator": "^7.7.4",
"@babel/plugin-proposal-optional-chaining": "^7.7.5",
"@babel/plugin-transform-modules-amd": "^7.5.0",
"@babel/plugin-transform-runtime": "^7.6.0",
"@babel/plugin-transform-typescript": "^7.7.4",
"@babel/polyfill": "^7.7.0",
"@babel/preset-env": "^7.7.0",
"@babel/runtime": "^7.7.0",
Expand Down
41 changes: 40 additions & 1 deletion yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -477,6 +477,14 @@
"@babel/helper-plugin-utils" "^7.0.0"
"@babel/plugin-syntax-json-strings" "^7.2.0"

"@babel/plugin-proposal-nullish-coalescing-operator@^7.7.4":
version "7.7.4"
resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.7.4.tgz#7db302c83bc30caa89e38fee935635ef6bd11c28"
integrity sha512-TbYHmr1Gl1UC7Vo2HVuj/Naci5BEGNZ0AJhzqD2Vpr6QPFWpUmBRLrIDjedzx7/CShq0bRDS2gI4FIs77VHLVQ==
dependencies:
"@babel/helper-plugin-utils" "^7.0.0"
"@babel/plugin-syntax-nullish-coalescing-operator" "^7.7.4"

"@babel/plugin-proposal-object-rest-spread@^7.6.2":
version "7.6.2"
resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.6.2.tgz#8ffccc8f3a6545e9f78988b6bf4fe881b88e8096"
Expand All @@ -493,6 +501,14 @@
"@babel/helper-plugin-utils" "^7.0.0"
"@babel/plugin-syntax-optional-catch-binding" "^7.2.0"

"@babel/plugin-proposal-optional-chaining@^7.7.5":
version "7.7.5"
resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.7.5.tgz#f0835f044cef85b31071a924010a2a390add11d4"
integrity sha512-sOwFqT8JSchtJeDD+CjmWCaiFoLxY4Ps7NjvwHC/U7l4e9i5pTRNt8nDMIFSOUL+ncFbYSwruHM8WknYItWdXw==
dependencies:
"@babel/helper-plugin-utils" "^7.0.0"
"@babel/plugin-syntax-optional-chaining" "^7.7.4"

"@babel/plugin-proposal-unicode-property-regex@^7.7.0":
version "7.7.0"
resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.7.0.tgz#549fe1717a1bd0a2a7e63163841cb37e78179d5d"
Expand Down Expand Up @@ -529,6 +545,13 @@
dependencies:
"@babel/helper-plugin-utils" "^7.0.0"

"@babel/plugin-syntax-nullish-coalescing-operator@^7.7.4":
version "7.7.4"
resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.7.4.tgz#e53b751d0c3061b1ba3089242524b65a7a9da12b"
integrity sha512-XKh/yIRPiQTOeBg0QJjEus5qiSKucKAiApNtO1psqG7D17xmE+X2i5ZqBEuSvo0HRuyPaKaSN/Gy+Ha9KFQolw==
dependencies:
"@babel/helper-plugin-utils" "^7.0.0"

"@babel/plugin-syntax-object-rest-spread@^7.2.0":
version "7.2.0"
resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.2.0.tgz#3b7a3e733510c57e820b9142a6579ac8b0dfad2e"
Expand All @@ -543,14 +566,21 @@
dependencies:
"@babel/helper-plugin-utils" "^7.0.0"

"@babel/plugin-syntax-optional-chaining@^7.7.4":
version "7.7.4"
resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.7.4.tgz#c91fdde6de85d2eb8906daea7b21944c3610c901"
integrity sha512-2MqYD5WjZSbJdUagnJvIdSfkb/ucOC9/1fRJxm7GAxY6YQLWlUvkfxoNbUPcPLHJyetKUDQ4+yyuUyAoc0HriA==
dependencies:
"@babel/helper-plugin-utils" "^7.0.0"

"@babel/plugin-syntax-top-level-await@^7.7.0":
version "7.7.0"
resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.7.0.tgz#f5699549f50bbe8d12b1843a4e82f0a37bb65f4d"
integrity sha512-hi8FUNiFIY1fnUI2n1ViB1DR0R4QeK4iHcTlW6aJkrPoTdb8Rf1EMQ6GT3f67DDkYyWgew9DFoOZ6gOoEsdzTA==
dependencies:
"@babel/helper-plugin-utils" "^7.0.0"

"@babel/plugin-syntax-typescript@^7.2.0":
"@babel/plugin-syntax-typescript@^7.2.0", "@babel/plugin-syntax-typescript@^7.7.4":
version "7.7.4"
resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.7.4.tgz#5d037ffa10f3b25a16f32570ebbe7a8c2efa304b"
integrity sha512-77blgY18Hud4NM1ggTA8xVT/dBENQf17OpiToSa2jSmEY3fWXD2jwrdVlO4kq5yzUTeF15WSQ6b4fByNvJcjpQ==
Expand Down Expand Up @@ -803,6 +833,15 @@
dependencies:
"@babel/helper-plugin-utils" "^7.0.0"

"@babel/plugin-transform-typescript@^7.7.4":
version "7.7.4"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.7.4.tgz#2974fd05f4e85c695acaf497f432342de9fc0636"
integrity sha512-X8e3tcPEKnwwPVG+vP/vSqEShkwODOEeyQGod82qrIuidwIrfnsGn11qPM1jBLF4MqguTXXYzm58d0dY+/wdpg==
dependencies:
"@babel/helper-create-class-features-plugin" "^7.7.4"
"@babel/helper-plugin-utils" "^7.0.0"
"@babel/plugin-syntax-typescript" "^7.7.4"

"@babel/plugin-transform-typescript@~7.4.0":
version "7.4.5"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.4.5.tgz#ab3351ba35307b79981993536c93ff8be050ba28"
Expand Down