Skip to content

Commit 670773f

Browse files
author
Robert Jackson
authored
Merge pull request #400 from brendenpalmer/bpalmer/fix-ts-bug
Update `_shouldHandleTypeScript` to read from `pkg.dependencies` instead of relying on `addons`
2 parents 88a8c81 + 12aa427 commit 670773f

File tree

4 files changed

+168
-57
lines changed

4 files changed

+168
-57
lines changed

index.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ module.exports = {
104104
},
105105

106106
getSupportedExtensions(config = {}) {
107-
return _getExtensions(config, this.parent);
107+
return _getExtensions(config, this.parent, this.project);
108108
},
109109

110110
_buildBroccoliBabelTranspilerOptions(config = {}) {
@@ -160,7 +160,7 @@ module.exports = {
160160
let BabelTranspiler = require('broccoli-babel-transpiler');
161161
let transpilationInput = postDebugTree;
162162

163-
if (_shouldHandleTypeScript(config, this.parent)) {
163+
if (_shouldHandleTypeScript(config, this.parent, this.project)) {
164164
let Funnel = require('broccoli-funnel');
165165
let inputWithoutDeclarations = new Funnel(transpilationInput, { exclude: ['**/*.d.ts'] });
166166
transpilationInput = this._debugTree(inputWithoutDeclarations, `${description}:filtered-input`);
@@ -175,7 +175,7 @@ module.exports = {
175175
setupPreprocessorRegistry(type, registry) {
176176
registry.add('js', {
177177
name: 'ember-cli-babel',
178-
ext: _getExtensions(this._getAddonOptions(), this.parent),
178+
ext: _getExtensions(this._getAddonOptions(), this.parent, this.project),
179179
toTree: (tree) => this.transpileTree(tree)
180180
});
181181
},

lib/babel-options-util.js

Lines changed: 62 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
const VersionChecker = require("ember-cli-version-checker");
2+
const resolvePackagePath = require("resolve-package-path");
23
const clone = require("clone");
34
const semver = require("semver");
45

@@ -264,10 +265,10 @@ function _getHelperVersion(project) {
264265
return APP_BABEL_RUNTIME_VERSION.get(project);
265266
}
266267

267-
function _buildClassFeaturePluginConstraints(constraints, config, parent) {
268+
function _buildClassFeaturePluginConstraints(constraints, config, parent, project) {
268269
// With versions of ember-cli-typescript < 4.0, class feature plugins like
269270
// @babel/plugin-proposal-class-properties were run before the TS transform.
270-
if (!_shouldHandleTypeScript(config, parent)) {
271+
if (!_shouldHandleTypeScript(config, parent, project)) {
271272
constraints.before = constraints.before || [];
272273
constraints.before.push("@babel/plugin-transform-typescript");
273274
}
@@ -295,7 +296,8 @@ function _addDecoratorPlugins(plugins, options, config, parent, project) {
295296
before: ["@babel/plugin-proposal-class-properties"],
296297
},
297298
config,
298-
parent
299+
parent,
300+
project
299301
)
300302
);
301303
}
@@ -320,7 +322,8 @@ function _addDecoratorPlugins(plugins, options, config, parent, project) {
320322
after: ["@babel/plugin-proposal-decorators"],
321323
},
322324
config,
323-
parent
325+
parent,
326+
project
324327
)
325328
);
326329
}
@@ -389,8 +392,8 @@ function _parentName(parent) {
389392
return parentName;
390393
}
391394

392-
function _getExtensions(config, parent) {
393-
let shouldHandleTypeScript = _shouldHandleTypeScript(config, parent);
395+
function _getExtensions(config, parent, project) {
396+
let shouldHandleTypeScript = _shouldHandleTypeScript(config, parent, project);
394397
let emberCLIBabelConfig = config["ember-cli-babel"] || {};
395398
return (
396399
emberCLIBabelConfig.extensions ||
@@ -404,18 +407,63 @@ function _shouldIncludeDecoratorPlugins(config) {
404407
return customOptions.disableDecoratorTransforms !== true;
405408
}
406409

407-
function _shouldHandleTypeScript(config, parent) {
410+
/**
411+
* Returns whether we should handle TypeScript (based on the existence of
412+
* `ember-cli-typescript` as a depenency). It's worth noting that we parse
413+
* the `package.json` deps/devDeps directly (rather than using `addons` on
414+
* the parent) because it's possible for `ember-cli-typescript` not to exist
415+
* on the addons array, even if it is a dependency.
416+
*
417+
* Some more context:
418+
*
419+
* `ember-cli-typescript` returns a stable cache key so its possible for it to
420+
* be deduped as part of `ember-engines`. The reason this is important is because
421+
* `ember-engines` dedupe is _stateful_ so it's possible for `ember-cli-typescript`
422+
* to not be part of the addons array when `ember-cli-babel` is running.
423+
*
424+
* For more info on `ember-engines` dedupe logic:
425+
* https://github.com/ember-engines/ember-engines/blob/master/packages/ember-engines/lib/utils/deeply-non-duplicated-addon.js#L35
426+
*
427+
* @name _shouldHandleTypeScript
428+
* @returns {boolean}
429+
*/
430+
function _shouldHandleTypeScript(config, parent, project) {
408431
let emberCLIBabelConfig = config["ember-cli-babel"] || {};
432+
409433
if (typeof emberCLIBabelConfig.enableTypeScriptTransform === "boolean") {
410434
return emberCLIBabelConfig.enableTypeScriptTransform;
411435
}
412-
let typeScriptAddon =
413-
parent.addons &&
414-
parent.addons.find((a) => a.name === "ember-cli-typescript");
415-
return (
416-
typeof typeScriptAddon !== "undefined" &&
417-
semver.gte(typeScriptAddon.pkg.version, "4.0.0-alpha.1")
418-
);
436+
437+
let pkg = parent.pkg;
438+
439+
if (!pkg) {
440+
return false;
441+
}
442+
443+
let dependencies;
444+
445+
// consider `dependencies` and `devDependencies` if the parent is the project
446+
// (`ember-cli` uses both in this case), otherwise only care about `dependencies`
447+
if (parent === project) {
448+
dependencies = Object.assign({}, pkg.dependencies, pkg.devDependencies);
449+
} else {
450+
dependencies = pkg.dependencies || {};
451+
}
452+
453+
let tsDependency = dependencies["ember-cli-typescript"];
454+
455+
if (tsDependency !== undefined) {
456+
let tsPkgPath = resolvePackagePath("ember-cli-typescript", parent.root);
457+
458+
if (tsPkgPath === null) {
459+
return false;
460+
}
461+
462+
let tsPkg = require(tsPkgPath);
463+
return semver.gte(tsPkg.version, "4.0.0-alpha.1");
464+
}
465+
466+
return false;
419467
}
420468

421469
function _getAddonProvidedConfig(addonOptions) {

lib/get-babel-options.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ module.exports = function getBabelOptions(config, appInstance) {
1818
let { parent, project } = appInstance;
1919
let addonProvidedConfig = _getAddonProvidedConfig(config);
2020
let shouldIncludeHelpers = _shouldIncludeHelpers(config, appInstance);
21-
let shouldHandleTypeScript = _shouldHandleTypeScript(config, parent);
21+
let shouldHandleTypeScript = _shouldHandleTypeScript(config, parent, project);
2222
let shouldIncludeDecoratorPlugins = _shouldIncludeDecoratorPlugins(config);
2323

2424
let emberCLIBabelConfig = config["ember-cli-babel"];

node-tests/addon-test.js

Lines changed: 102 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -800,14 +800,51 @@ describe('ember-cli-babel', function() {
800800
});
801801

802802
describe('TypeScript transpilation', function() {
803-
beforeEach(function() {
804-
this.addon.parent.addons.push({
805-
name: 'ember-cli-typescript',
806-
pkg: {
807-
version: '4.0.0-alpha.1'
808-
}
803+
let input;
804+
let output;
805+
let subject;
806+
let project;
807+
let unlink;
808+
809+
beforeEach(co.wrap(function*() {
810+
let fixturifyProject = new FixturifyProject('whatever', '0.0.1');
811+
fixturifyProject.addDependency('ember-cli-typescript', '4.0.0-alpha.1', addon => {
812+
return prepareAddon(addon);
809813
});
810-
});
814+
fixturifyProject.addDependency('ember-cli-babel', 'babel/ember-cli-babel#master');
815+
let pkg = JSON.parse(fixturifyProject.toJSON('package.json'));
816+
fixturifyProject.writeSync();
817+
818+
let linkPath = path.join(fixturifyProject.root, 'whatever/node_modules/ember-cli-babel');
819+
let addonPath = path.resolve(__dirname, '../');
820+
rimraf.sync(linkPath);
821+
fs.symlinkSync(addonPath, linkPath, 'junction');
822+
unlink = () => {
823+
fs.unlinkSync(linkPath);
824+
};
825+
826+
let cli = new MockCLI();
827+
let root = path.join(fixturifyProject.root, 'whatever');
828+
project = new EmberProject(root, pkg, cli.ui, cli);
829+
project.initializeAddons();
830+
this.addon = project.addons.find(a => { return a.name === 'ember-cli-babel'; });
831+
input = yield createTempDir();
832+
}));
833+
834+
afterEach(co.wrap(function*() {
835+
unlink();
836+
837+
if (input) {
838+
yield input.dispose();
839+
}
840+
841+
if (output) {
842+
yield output.dispose();
843+
}
844+
845+
// shut down workers after the tests are run so that mocha doesn't hang
846+
yield terminateWorkerPool();
847+
}));
811848

812849
it('should transpile .ts files', co.wrap(function*() {
813850
input.write({ 'foo.ts': `let foo: string = "hi";` });
@@ -967,41 +1004,67 @@ describe('ember-cli-babel', function() {
9671004
});
9681005

9691006
describe('_shouldHandleTypeScript', function() {
1007+
let project;
1008+
let unlink;
1009+
1010+
let setupTsAddon = function*(context, version = '4.0.0-alpha.1') {
1011+
let fixturifyProject = new FixturifyProject('whatever', '0.0.1');
1012+
fixturifyProject.addDependency('ember-cli-typescript', version, addon => {
1013+
return prepareAddon(addon);
1014+
});
1015+
fixturifyProject.addDependency('ember-cli-babel', 'babel/ember-cli-babel#master');
1016+
let pkg = JSON.parse(fixturifyProject.toJSON('package.json'));
1017+
fixturifyProject.writeSync();
1018+
1019+
let linkPath = path.join(fixturifyProject.root, 'whatever/node_modules/ember-cli-babel');
1020+
let addonPath = path.resolve(__dirname, '../');
1021+
rimraf.sync(linkPath);
1022+
fs.symlinkSync(addonPath, linkPath, 'junction');
1023+
unlink = () => {
1024+
fs.unlinkSync(linkPath);
1025+
};
1026+
1027+
let cli = new MockCLI();
1028+
let root = path.join(fixturifyProject.root, 'whatever');
1029+
project = new EmberProject(root, pkg, cli.ui, cli);
1030+
project.initializeAddons();
1031+
context.addon = project.addons.find(a => { return a.name === 'ember-cli-babel'; });
1032+
input = yield createTempDir();
1033+
}
1034+
1035+
afterEach(co.wrap(function*() {
1036+
if (unlink) {
1037+
unlink();
1038+
unlink = undefined;
1039+
}
1040+
1041+
// shut down workers after the tests are run so that mocha doesn't hang
1042+
yield terminateWorkerPool();
1043+
}));
1044+
9701045
it('should return false by default', function() {
971-
expect(_shouldHandleTypeScript({}, this.addon.parent)).to.be.false;
1046+
expect(_shouldHandleTypeScript({}, this.addon.parent, this.addon.project)).to.be.false;
9721047
});
973-
it('should return true when ember-cli-typescript >= 4.0.0-alpha.1 is installed', function() {
974-
this.addon.parent.addons.push({
975-
name: 'ember-cli-typescript',
976-
pkg: {
977-
version: '4.0.0-alpha.1',
978-
},
979-
});
980-
expect(_shouldHandleTypeScript({}, this.addon.parent)).to.be.true;
1048+
it('should return true when ember-cli-typescript >= 4.0.0-alpha.1 is installed', function*() {
1049+
yield setupTsAddon(this);
1050+
expect(_shouldHandleTypeScript({}, this.addon.parent, this.addon.project)).to.be.true;
9811051
});
982-
it('should return false when ember-cli-typescript < 4.0.0-alpha.1 is installed', function() {
983-
this.addon.parent.addons.push({
984-
name: 'ember-cli-typescript',
985-
pkg: {
986-
version: '3.0.0',
987-
},
988-
});
989-
expect(_shouldHandleTypeScript({}, this.addon.parent)).to.be.false;
1052+
it('should return false when ember-cli-typescript < 4.0.0-alpha.1 is installed', function*() {
1053+
yield setupTsAddon(this, '3.0.0');
1054+
expect(_shouldHandleTypeScript({}, this.addon.parent, this.addon.project)).to.be.false;
9901055
});
991-
it('should return true when the TypeScript transform is manually enabled', function() {
992-
expect(_shouldHandleTypeScript({ 'ember-cli-babel': { enableTypeScriptTransform: true } }, this.addon.parent)).to.be.true;
1056+
it('should return true when the TypeScript transform is manually enabled', function*() {
1057+
yield setupTsAddon(this, '3.0.0');
1058+
expect(_shouldHandleTypeScript({ 'ember-cli-babel': { enableTypeScriptTransform: true } }, this.addon.parent, this.addon.project)).to.be.true;
9931059
});
1060+
9941061
it('should return false when the TypeScript transforms is manually disabled', function() {
995-
expect(_shouldHandleTypeScript({ 'ember-cli-babel': { enableTypeScriptTransform: false } }, this.addon.parent)).to.be.false;
1062+
expect(_shouldHandleTypeScript({ 'ember-cli-babel': { enableTypeScriptTransform: false } }, this.addon.parent, this.addon.project)).to.be.false;
9961063
});
997-
it('should return false when the TypeScript transform is manually disabled, even when ember-cli-typescript >= 4.0.0-alpha.1 is installed', function() {
998-
this.addon.parent.addons.push({
999-
name: 'ember-cli-typescript',
1000-
pkg: {
1001-
version: '4.0.0-alpha.1',
1002-
},
1003-
});
1004-
expect(_shouldHandleTypeScript({ 'ember-cli-babel': { enableTypeScriptTransform: false } }, this.addon.parent)).to.be.false;
1064+
1065+
it('should return false when the TypeScript transform is manually disabled, even when ember-cli-typescript >= 4.0.0-alpha.1 is installed', function*() {
1066+
yield setupTsAddon(this, '4.1.0');
1067+
expect(_shouldHandleTypeScript({ 'ember-cli-babel': { enableTypeScriptTransform: false } }, this.addon.parent, this.addon.project)).to.be.false;
10051068
});
10061069
});
10071070

@@ -1177,17 +1240,17 @@ describe('ember-cli-babel', function() {
11771240

11781241
describe('_getExtensions', function() {
11791242
it('defaults to js only', function() {
1180-
expect(_getExtensions({}, this.addon.parent)).to.have.members(['js']);
1243+
expect(_getExtensions({}, this.addon.parent, this.addon.project)).to.have.members(['js']);
11811244
});
11821245
it('adds ts automatically', function() {
11831246
this.addon._shouldHandleTypeScript = function() { return true; }
1184-
expect(_getExtensions({ 'ember-cli-babel': { enableTypeScriptTransform: true }}, this.addon.parent)).to.have.members(['js', 'ts']);
1247+
expect(_getExtensions({ 'ember-cli-babel': { enableTypeScriptTransform: true } }, this.addon.parent, this.addon.project)).to.have.members(['js', 'ts']);
11851248
});
11861249
it('respects user-configured extensions', function() {
1187-
expect(_getExtensions({ 'ember-cli-babel': { extensions: ['coffee'] } }, this.addon.parent)).to.have.members(['coffee']);
1250+
expect(_getExtensions({ 'ember-cli-babel': { extensions: ['coffee'] } }, this.addon.parent, this.addon.project)).to.have.members(['coffee']);
11881251
});
11891252
it('respects user-configured extensions even when adding TS plugin', function() {
1190-
expect(_getExtensions({ 'ember-cli-babel': { enableTypeScriptTransform: true, extensions: ['coffee'] } }, this.addon.parent)).to.have.members(['coffee']);
1253+
expect(_getExtensions({ 'ember-cli-babel': { enableTypeScriptTransform: true, extensions: ['coffee'] } }, this.addon.parent, this.addon.project)).to.have.members(['coffee']);
11911254
});
11921255
});
11931256

0 commit comments

Comments
 (0)