From 69ded966888d7974b1b903c3e7fca34b50b4986f Mon Sep 17 00:00:00 2001 From: Brenden Palmer Date: Fri, 23 Apr 2021 13:50:33 -0400 Subject: [PATCH] Update `_shouldHandleTypeScript` to read from `pkg.dependencies` instead of relying on `addons` --- index.js | 6 +- lib/babel-options-util.js | 54 +++++++++++---- lib/get-babel-options.js | 2 +- node-tests/addon-test.js | 141 +++++++++++++++++++++++++++----------- 4 files changed, 146 insertions(+), 57 deletions(-) diff --git a/index.js b/index.js index ad0463df..e55e0a9e 100644 --- a/index.js +++ b/index.js @@ -104,7 +104,7 @@ module.exports = { }, getSupportedExtensions(config = {}) { - return _getExtensions(config, this.parent); + return _getExtensions(config, this.parent, this.project); }, _buildBroccoliBabelTranspilerOptions(config = {}) { @@ -160,7 +160,7 @@ module.exports = { let BabelTranspiler = require('broccoli-babel-transpiler'); let transpilationInput = postDebugTree; - if (_shouldHandleTypeScript(config, this.parent)) { + if (_shouldHandleTypeScript(config, this.parent, this.project)) { let Funnel = require('broccoli-funnel'); let inputWithoutDeclarations = new Funnel(transpilationInput, { exclude: ['**/*.d.ts'] }); transpilationInput = this._debugTree(inputWithoutDeclarations, `${description}:filtered-input`); @@ -175,7 +175,7 @@ module.exports = { setupPreprocessorRegistry(type, registry) { registry.add('js', { name: 'ember-cli-babel', - ext: _getExtensions(this._getAddonOptions(), this.parent), + ext: _getExtensions(this._getAddonOptions(), this.parent, this.project), toTree: (tree) => this.transpileTree(tree) }); }, diff --git a/lib/babel-options-util.js b/lib/babel-options-util.js index f48a8956..29467ca5 100644 --- a/lib/babel-options-util.js +++ b/lib/babel-options-util.js @@ -1,4 +1,5 @@ const VersionChecker = require("ember-cli-version-checker"); +const resolvePackagePath = require("resolve-package-path"); const clone = require("clone"); const semver = require("semver"); @@ -264,10 +265,10 @@ function _getHelperVersion(project) { return APP_BABEL_RUNTIME_VERSION.get(project); } -function _buildClassFeaturePluginConstraints(constraints, config, parent) { +function _buildClassFeaturePluginConstraints(constraints, config, parent, project) { // With versions of ember-cli-typescript < 4.0, class feature plugins like // @babel/plugin-proposal-class-properties were run before the TS transform. - if (!_shouldHandleTypeScript(config, parent)) { + if (!_shouldHandleTypeScript(config, parent, project)) { constraints.before = constraints.before || []; constraints.before.push("@babel/plugin-transform-typescript"); } @@ -295,7 +296,8 @@ function _addDecoratorPlugins(plugins, options, config, parent, project) { before: ["@babel/plugin-proposal-class-properties"], }, config, - parent + parent, + project ) ); } @@ -320,7 +322,8 @@ function _addDecoratorPlugins(plugins, options, config, parent, project) { after: ["@babel/plugin-proposal-decorators"], }, config, - parent + parent, + project ) ); } @@ -389,8 +392,8 @@ function _parentName(parent) { return parentName; } -function _getExtensions(config, parent) { - let shouldHandleTypeScript = _shouldHandleTypeScript(config, parent); +function _getExtensions(config, parent, project) { + let shouldHandleTypeScript = _shouldHandleTypeScript(config, parent, project); let emberCLIBabelConfig = config["ember-cli-babel"] || {}; return ( emberCLIBabelConfig.extensions || @@ -404,18 +407,41 @@ function _shouldIncludeDecoratorPlugins(config) { return customOptions.disableDecoratorTransforms !== true; } -function _shouldHandleTypeScript(config, parent) { +function _shouldHandleTypeScript(config, parent, project) { let emberCLIBabelConfig = config["ember-cli-babel"] || {}; + if (typeof emberCLIBabelConfig.enableTypeScriptTransform === "boolean") { return emberCLIBabelConfig.enableTypeScriptTransform; } - let typeScriptAddon = - parent.addons && - parent.addons.find((a) => a.name === "ember-cli-typescript"); - return ( - typeof typeScriptAddon !== "undefined" && - semver.gte(typeScriptAddon.pkg.version, "4.0.0-alpha.1") - ); + + let pkg = parent.pkg; + + if (!pkg) { + return false; + } + + let dependencies; + + if (parent === project) { + dependencies = Object.assign({}, pkg.dependencies, pkg.devDependencies); + } else { + dependencies = pkg.dependencies || {}; + } + + let tsDependency = dependencies["ember-cli-typescript"]; + + if (tsDependency !== undefined) { + let tsPkgPath = resolvePackagePath("ember-cli-typescript", parent.root); + + if (tsPkgPath === null) { + return false; + } + + let tsPkg = require(tsPkgPath); + return semver.gte(tsPkg.version, "4.0.0-alpha.1"); + } + + return false; } function _getAddonProvidedConfig(addonOptions) { diff --git a/lib/get-babel-options.js b/lib/get-babel-options.js index 7b02ef54..41f73f7e 100644 --- a/lib/get-babel-options.js +++ b/lib/get-babel-options.js @@ -18,7 +18,7 @@ module.exports = function getBabelOptions(config, appInstance) { let { parent, project } = appInstance; let addonProvidedConfig = _getAddonProvidedConfig(config); let shouldIncludeHelpers = _shouldIncludeHelpers(config, appInstance); - let shouldHandleTypeScript = _shouldHandleTypeScript(config, parent); + let shouldHandleTypeScript = _shouldHandleTypeScript(config, parent, project); let shouldIncludeDecoratorPlugins = _shouldIncludeDecoratorPlugins(config); let emberCLIBabelConfig = config["ember-cli-babel"]; diff --git a/node-tests/addon-test.js b/node-tests/addon-test.js index d3d5a1bd..903754bd 100644 --- a/node-tests/addon-test.js +++ b/node-tests/addon-test.js @@ -800,14 +800,51 @@ describe('ember-cli-babel', function() { }); describe('TypeScript transpilation', function() { - beforeEach(function() { - this.addon.parent.addons.push({ - name: 'ember-cli-typescript', - pkg: { - version: '4.0.0-alpha.1' - } + let input; + let output; + let subject; + let project; + let unlink; + + beforeEach(co.wrap(function*() { + let fixturifyProject = new FixturifyProject('whatever', '0.0.1'); + fixturifyProject.addDependency('ember-cli-typescript', '4.0.0-alpha.1', addon => { + return prepareAddon(addon); }); - }); + fixturifyProject.addDependency('ember-cli-babel', 'babel/ember-cli-babel#master'); + let pkg = JSON.parse(fixturifyProject.toJSON('package.json')); + fixturifyProject.writeSync(); + + let linkPath = path.join(fixturifyProject.root, 'whatever/node_modules/ember-cli-babel'); + let addonPath = path.resolve(__dirname, '../'); + rimraf.sync(linkPath); + fs.symlinkSync(addonPath, linkPath, 'junction'); + unlink = () => { + fs.unlinkSync(linkPath); + }; + + let cli = new MockCLI(); + let root = path.join(fixturifyProject.root, 'whatever'); + project = new EmberProject(root, pkg, cli.ui, cli); + project.initializeAddons(); + this.addon = project.addons.find(a => { return a.name === 'ember-cli-babel'; }); + input = yield createTempDir(); + })); + + afterEach(co.wrap(function*() { + unlink(); + + if (input) { + yield input.dispose(); + } + + if (output) { + yield output.dispose(); + } + + // shut down workers after the tests are run so that mocha doesn't hang + yield terminateWorkerPool(); + })); it('should transpile .ts files', co.wrap(function*() { input.write({ 'foo.ts': `let foo: string = "hi";` }); @@ -967,41 +1004,67 @@ describe('ember-cli-babel', function() { }); describe('_shouldHandleTypeScript', function() { + let project; + let unlink; + + let setupTsAddon = function*(context, version = '4.0.0-alpha.1') { + let fixturifyProject = new FixturifyProject('whatever', '0.0.1'); + fixturifyProject.addDependency('ember-cli-typescript', version, addon => { + return prepareAddon(addon); + }); + fixturifyProject.addDependency('ember-cli-babel', 'babel/ember-cli-babel#master'); + let pkg = JSON.parse(fixturifyProject.toJSON('package.json')); + fixturifyProject.writeSync(); + + let linkPath = path.join(fixturifyProject.root, 'whatever/node_modules/ember-cli-babel'); + let addonPath = path.resolve(__dirname, '../'); + rimraf.sync(linkPath); + fs.symlinkSync(addonPath, linkPath, 'junction'); + unlink = () => { + fs.unlinkSync(linkPath); + }; + + let cli = new MockCLI(); + let root = path.join(fixturifyProject.root, 'whatever'); + project = new EmberProject(root, pkg, cli.ui, cli); + project.initializeAddons(); + context.addon = project.addons.find(a => { return a.name === 'ember-cli-babel'; }); + input = yield createTempDir(); + } + + afterEach(co.wrap(function*() { + if (unlink) { + unlink(); + unlink = undefined; + } + + // shut down workers after the tests are run so that mocha doesn't hang + yield terminateWorkerPool(); + })); + it('should return false by default', function() { - expect(_shouldHandleTypeScript({}, this.addon.parent)).to.be.false; + expect(_shouldHandleTypeScript({}, this.addon.parent, this.addon.project)).to.be.false; }); - it('should return true when ember-cli-typescript >= 4.0.0-alpha.1 is installed', function() { - this.addon.parent.addons.push({ - name: 'ember-cli-typescript', - pkg: { - version: '4.0.0-alpha.1', - }, - }); - expect(_shouldHandleTypeScript({}, this.addon.parent)).to.be.true; + it('should return true when ember-cli-typescript >= 4.0.0-alpha.1 is installed', function*() { + yield setupTsAddon(this); + expect(_shouldHandleTypeScript({}, this.addon.parent, this.addon.project)).to.be.true; }); - it('should return false when ember-cli-typescript < 4.0.0-alpha.1 is installed', function() { - this.addon.parent.addons.push({ - name: 'ember-cli-typescript', - pkg: { - version: '3.0.0', - }, - }); - expect(_shouldHandleTypeScript({}, this.addon.parent)).to.be.false; + it('should return false when ember-cli-typescript < 4.0.0-alpha.1 is installed', function*() { + yield setupTsAddon(this, '3.0.0'); + expect(_shouldHandleTypeScript({}, this.addon.parent, this.addon.project)).to.be.false; }); - it('should return true when the TypeScript transform is manually enabled', function() { - expect(_shouldHandleTypeScript({ 'ember-cli-babel': { enableTypeScriptTransform: true } }, this.addon.parent)).to.be.true; + it('should return true when the TypeScript transform is manually enabled', function*() { + yield setupTsAddon(this, '3.0.0'); + expect(_shouldHandleTypeScript({ 'ember-cli-babel': { enableTypeScriptTransform: true } }, this.addon.parent, this.addon.project)).to.be.true; }); + it('should return false when the TypeScript transforms is manually disabled', function() { - expect(_shouldHandleTypeScript({ 'ember-cli-babel': { enableTypeScriptTransform: false } }, this.addon.parent)).to.be.false; + expect(_shouldHandleTypeScript({ 'ember-cli-babel': { enableTypeScriptTransform: false } }, this.addon.parent, this.addon.project)).to.be.false; }); - it('should return false when the TypeScript transform is manually disabled, even when ember-cli-typescript >= 4.0.0-alpha.1 is installed', function() { - this.addon.parent.addons.push({ - name: 'ember-cli-typescript', - pkg: { - version: '4.0.0-alpha.1', - }, - }); - expect(_shouldHandleTypeScript({ 'ember-cli-babel': { enableTypeScriptTransform: false } }, this.addon.parent)).to.be.false; + + it('should return false when the TypeScript transform is manually disabled, even when ember-cli-typescript >= 4.0.0-alpha.1 is installed', function*() { + yield setupTsAddon(this, '4.1.0'); + expect(_shouldHandleTypeScript({ 'ember-cli-babel': { enableTypeScriptTransform: false } }, this.addon.parent, this.addon.project)).to.be.false; }); }); @@ -1177,17 +1240,17 @@ describe('ember-cli-babel', function() { describe('_getExtensions', function() { it('defaults to js only', function() { - expect(_getExtensions({}, this.addon.parent)).to.have.members(['js']); + expect(_getExtensions({}, this.addon.parent, this.addon.project)).to.have.members(['js']); }); it('adds ts automatically', function() { this.addon._shouldHandleTypeScript = function() { return true; } - expect(_getExtensions({ 'ember-cli-babel': { enableTypeScriptTransform: true }}, this.addon.parent)).to.have.members(['js', 'ts']); + expect(_getExtensions({ 'ember-cli-babel': { enableTypeScriptTransform: true } }, this.addon.parent, this.addon.project)).to.have.members(['js', 'ts']); }); it('respects user-configured extensions', function() { - expect(_getExtensions({ 'ember-cli-babel': { extensions: ['coffee'] } }, this.addon.parent)).to.have.members(['coffee']); + expect(_getExtensions({ 'ember-cli-babel': { extensions: ['coffee'] } }, this.addon.parent, this.addon.project)).to.have.members(['coffee']); }); it('respects user-configured extensions even when adding TS plugin', function() { - expect(_getExtensions({ 'ember-cli-babel': { enableTypeScriptTransform: true, extensions: ['coffee'] } }, this.addon.parent)).to.have.members(['coffee']); + expect(_getExtensions({ 'ember-cli-babel': { enableTypeScriptTransform: true, extensions: ['coffee'] } }, this.addon.parent, this.addon.project)).to.have.members(['coffee']); }); });