Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 18 additions & 7 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ const {
_getExtensions,
_parentName,
_shouldHighlightCode,
isBabel8,
} = require("./lib/babel-options-util");

const VersionChecker = require('ember-cli-version-checker');
Expand Down Expand Up @@ -139,8 +140,12 @@ module.exports = {
};

if (shouldCompileModules) {
options.moduleIds = true;
options.getModuleId = require("./lib/relative-module-paths").getRelativeModulePath;
// In Babel 8, the root-level `moduleIds` and `getModuleId` options have
// been moved to plugin options (handled in _getModulesPlugin).
if (!isBabel8()) {
options.moduleIds = true;
options.getModuleId = require("./lib/relative-module-paths").getRelativeModulePath;
}
}

options.highlightCode = _shouldHighlightCode(this.parent);
Expand Down Expand Up @@ -230,14 +235,20 @@ module.exports = {
},

_getHelpersPlugin() {
const runtimeOptions = {
version: this._getHelperVersion(),
regenerator: false,
};

// In Babel 8, the `useESModules` option has been removed.
if (!isBabel8()) {
runtimeOptions.useESModules = true;
}

return [
[
require.resolve('@babel/plugin-transform-runtime'),
{
version: this._getHelperVersion(),
regenerator: false,
useESModules: true
}
runtimeOptions,
]
]
},
Expand Down
54 changes: 45 additions & 9 deletions lib/babel-options-util.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ const VersionChecker = require("ember-cli-version-checker");
const resolvePackagePath = require("resolve-package-path");
const clone = require("clone");
const semver = require("semver");
const { isBabel8 } = require("./babel-version");

const APP_BABEL_RUNTIME_VERSION = new WeakMap();

Expand All @@ -27,18 +28,34 @@ function _getPresetEnv(config, project) {
delete presetOptions.plugins;
delete presetOptions.postTransformPlugins;

// In Babel 8, the `loose` and `spec` options have been removed from
// @babel/preset-env in favor of top-level `assumptions`.
if (isBabel8()) {
delete presetOptions.loose;
delete presetOptions.spec;
}

return [require.resolve("@babel/preset-env"), presetOptions];
}

function _getModulesPlugin() {
const resolvePath = require("./relative-module-paths")
.resolveRelativeModulePath;

const amdOptions = { noInterop: true };

// In Babel 8, the root-level `moduleIds` and `getModuleId` options have
// been moved to plugin options.
if (isBabel8()) {
amdOptions.moduleIds = true;
amdOptions.getModuleId = require("./relative-module-paths").getRelativeModulePath;
}

return [
[require.resolve("babel-plugin-module-resolver"), { resolvePath }],
[
require.resolve("@babel/plugin-transform-modules-amd"),
{ noInterop: true },
amdOptions,
],
];
}
Expand Down Expand Up @@ -274,14 +291,22 @@ function _getEmberDataPackagesPolyfill(config, parent) {
}
}
function _getHelpersPlugin(project) {
const runtimeOptions = {
version: _getHelperVersion(project),
regenerator: false,
};

// In Babel 8, the `useESModules` option has been removed from
// @babel/plugin-transform-runtime. ESM is now auto-detected via
// package.json#exports.
if (!isBabel8()) {
runtimeOptions.useESModules = true;
}

return [
[
require.resolve("@babel/plugin-transform-runtime"),
{
version: _getHelperVersion(project),
regenerator: false,
useESModules: true,
},
runtimeOptions,
],
];
}
Expand Down Expand Up @@ -320,9 +345,12 @@ function _addDecoratorPlugins(plugins, options, config, parent, project) {
);
}
} else {
// In Babel 8, unknown options cause errors, so we omit the `legacy`
// option that was passed in Babel 7.
const staticBlockOptions = isBabel8() ? {} : { legacy: true };
addPlugin(
plugins,
[require.resolve("@babel/plugin-transform-class-static-block"), { legacy: true }],
[require.resolve("@babel/plugin-transform-class-static-block"), staticBlockOptions],
_buildClassFeaturePluginConstraints(
{
before: ["@babel/plugin-proposal-decorators"],
Expand All @@ -343,9 +371,13 @@ function _addDecoratorPlugins(plugins, options, config, parent, project) {
);
}
} else {
// In Babel 8, the `legacy: true` option is replaced by `version: "legacy"`.
const decoratorOptions = isBabel8()
? { version: "legacy" }
: { legacy: true };
addPlugin(
plugins,
[require.resolve("@babel/plugin-proposal-decorators"), { legacy: true }],
[require.resolve("@babel/plugin-proposal-decorators"), decoratorOptions],
_buildClassFeaturePluginConstraints(
{
before: ["@babel/plugin-transform-class-properties"],
Expand Down Expand Up @@ -449,11 +481,14 @@ function _addTypeScriptPlugin(plugins, parent, project) {
);
}
} else {
// In Babel 8, `allowDeclareFields` is always enabled and the option has
// been removed. Passing it would cause a validation error.
const tsOptions = isBabel8() ? {} : { allowDeclareFields: true };
addPlugin(
plugins,
[
require.resolve("@babel/plugin-transform-typescript"),
{ allowDeclareFields: true },
tsOptions,
],
{
before: [
Expand Down Expand Up @@ -641,4 +676,5 @@ module.exports = {
_getModulesPlugin,
_getPresetEnv,
_shouldHighlightCode,
isBabel8,
};
53 changes: 53 additions & 0 deletions lib/babel-version.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
'use strict';

const semver = require("semver");
const resolvePackagePath = require("resolve-package-path");

let _babelMajorVersion;

/**
* Returns the major version of the installed @babel/core package.
* The result is cached for the lifetime of the process.
*
* @returns {number} The major version (e.g. 7 or 8)
*/
function getBabelMajorVersion() {
if (_babelMajorVersion !== undefined) return _babelMajorVersion;

const pkgPath = resolvePackagePath("@babel/core", __dirname);
if (pkgPath) {
const pkg = require(pkgPath);
_babelMajorVersion = semver.major(pkg.version);
} else {
_babelMajorVersion = 7;
}
return _babelMajorVersion;
}

/**
* Returns true if @babel/core v8 or higher is installed.
*
* @returns {boolean}
*/
function isBabel8() {
return getBabelMajorVersion() >= 8;
}

/**
* Reset the cached version (used in tests).
*/
function _resetBabelMajorVersion() {
_babelMajorVersion = undefined;
}

/**
* Override the cached Babel major version (used in tests).
* Pass `undefined` to reset to auto-detection.
*
* @param {number|undefined} version
*/
function _overrideBabelMajorVersion(version) {
_babelMajorVersion = version;
}

module.exports = { getBabelMajorVersion, isBabel8, _resetBabelMajorVersion, _overrideBabelMajorVersion };
8 changes: 7 additions & 1 deletion lib/ember-plugins.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
const semver = require("semver");
const resolvePackagePath = require("resolve-package-path");
const { isBabel8 } = require("./babel-version");

function _getDebugMacroPlugins(appRoot) {
const isProduction = process.env.EMBER_ENV === "production";
Expand Down Expand Up @@ -161,6 +162,11 @@ function _getModuleResolutionPlugins(config) {

function _getProposalDecoratorsAndClassPlugins(config) {
if (!config.shouldIgnoreDecoratorAndClassPlugins) {
// In Babel 8, `legacy: true` is replaced by `version: "legacy"`.
const decoratorOptions = isBabel8()
? { version: "legacy" }
: { legacy: true };

return [
/**
* Required for apps to use `@ember/template-compliation`
Expand All @@ -173,7 +179,7 @@ function _getProposalDecoratorsAndClassPlugins(config) {
* we need to compile it away.
*/
["@babel/plugin-transform-class-static-block"],
["@babel/plugin-proposal-decorators", { legacy: true }],
["@babel/plugin-proposal-decorators", decoratorOptions],
["@babel/plugin-transform-class-properties"],
];
}
Expand Down
Loading
Loading