Skip to content

Commit

Permalink
Merge pull request #683 from ember-cli/disable-modules-api-polyfill-w…
Browse files Browse the repository at this point in the history
…ith-latest

Disable the modules API polyfill on latest Ember
  • Loading branch information
rwjblue committed Mar 18, 2021
2 parents 9ef9507 + 3697751 commit d92706b
Show file tree
Hide file tree
Showing 10 changed files with 1,363 additions and 312 deletions.
57 changes: 54 additions & 3 deletions lib/colocated-babel-plugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@
module.exports = function (babel) {
let t = babel.types;

function makeSetComponentTemplateMemberExpression() {
function makeSetComponentTemplateExpression(state) {
if (!state.opts.requiresModuleApiPolyfill) {
return state._colocationEnsureImport('setComponentTemplate', '@ember/component');
}

return t.memberExpression(t.identifier('Ember'), t.identifier('_setComponentTemplate'));
}

Expand All @@ -15,6 +19,53 @@ module.exports = function (babel) {
name: 'ember-cli-htmlbars-colocation-template',

visitor: {
Program(path, state) {
let allAddedImports = {};

state._colocationEnsureImport = (exportName, moduleName) => {
let addedImports = (allAddedImports[moduleName] = allAddedImports[moduleName] || {});

if (addedImports[exportName]) return t.identifier(addedImports[exportName].name);

let importDeclarations = path.get('body').filter((n) => n.type === 'ImportDeclaration');

let preexistingImportDeclaration = importDeclarations.find(
(n) => n.get('source').get('value').node === moduleName
);

if (preexistingImportDeclaration) {
let importSpecifier = preexistingImportDeclaration
.get('specifiers')
.find(({ node }) => {
return exportName === 'default'
? t.isImportDefaultSpecifier(node)
: node.imported && node.imported.name === exportName;
});

if (importSpecifier) {
addedImports[exportName] = importSpecifier.node.local;
}
}

if (!addedImports[exportName]) {
let uid = path.scope.generateUidIdentifier(
exportName === 'default' ? moduleName : exportName
);
addedImports[exportName] = uid;

let newImportSpecifier =
exportName === 'default'
? t.importDefaultSpecifier(uid)
: t.importSpecifier(uid, t.identifier(exportName));

let newImport = t.importDeclaration([newImportSpecifier], t.stringLiteral(moduleName));
path.unshiftContainer('body', newImport);
}

return t.identifier(addedImports[exportName].name);
};
},

VariableDeclarator(path, state) {
if (path.node.id.name === '__COLOCATED_TEMPLATE__') {
state.colocatedTemplateFound = true;
Expand All @@ -38,7 +89,7 @@ module.exports = function (babel) {

state.setComponentTemplateInjected = true;
let defaultExportDeclaration = path.node.declaration;
let setComponentTemplateMemberExpression = makeSetComponentTemplateMemberExpression();
let setComponentTemplateMemberExpression = makeSetComponentTemplateExpression(state);
let colocatedTemplateIdentifier = makeColocatedTemplateIdentifier();

if (defaultExportDeclaration.type === 'ClassDeclaration') {
Expand Down Expand Up @@ -85,7 +136,7 @@ module.exports = function (babel) {
state.setComponentTemplateInjected = true;
path.parent.body.push(
t.expressionStatement(
t.callExpression(makeSetComponentTemplateMemberExpression(), [
t.callExpression(makeSetComponentTemplateExpression(state), [
makeColocatedTemplateIdentifier(),
defaultSpecifier.local,
])
Expand Down
15 changes: 12 additions & 3 deletions lib/ember-addon-main.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
const path = require('path');
const SilentError = require('silent-error');
const utils = require('./utils');
const VersionChecker = require('ember-cli-version-checker');

let registryInvocationCounter = 0;

Expand Down Expand Up @@ -62,7 +63,7 @@ module.exports = {
transpileTree(inputTree, htmlbarsOptions) {
const TemplateCompiler = require('./template-compiler-plugin');

return new TemplateCompiler(inputTree, htmlbarsOptions);
return new TemplateCompiler(inputTree, htmlbarsOptions, this._requiresModuleApiPolyfill);
},

setupPreprocessorRegistry(type, registry) {
Expand Down Expand Up @@ -169,6 +170,9 @@ module.exports = {

let isProduction = process.env.EMBER_ENV === 'production';

let checker = new VersionChecker(this.parent).for('ember-source', 'npm');
this._requiresModuleApiPolyfill = checker.exists() && checker.lt('3.27.0-alpha.1');

// This is an option intended to be used only be `ember-template-imports`.
// DO NOT USE THIS
let customModules =
Expand All @@ -190,7 +194,8 @@ module.exports = {
this.projectConfig(),
templateCompilerPath,
isProduction,
customModules
customModules,
this._requiresModuleApiPolyfill
);

babelPlugins.push(htmlbarsInlinePrecompilePlugin);
Expand All @@ -205,14 +210,18 @@ module.exports = {
projectConfig: this.projectConfig(),
templateCompilerPath,
modules: customModules,
requiresModuleApiPolyfill: this._requiresModuleApiPolyfill,
});

babelPlugins.push(htmlBarsPlugin);
}
}

if (this._shouldColocateTemplates() && !utils.isColocatedBabelPluginRegistered(babelPlugins)) {
babelPlugins.push(require.resolve('./colocated-babel-plugin'));
babelPlugins.push([
require.resolve('./colocated-babel-plugin'),
{ requiresModuleApiPolyfill: this._requiresModuleApiPolyfill },
]);
}
},

Expand Down
49 changes: 28 additions & 21 deletions lib/template-compiler-plugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ function rethrowBuildError(error) {
}

class TemplateCompiler extends Filter {
constructor(inputTree, _options) {
constructor(inputTree, _options, requiresModuleApiPolyfill = true) {
let options = _options || {};

if (!('persist' in options)) {
Expand All @@ -35,6 +35,7 @@ class TemplateCompiler extends Filter {

this.options = options;
this.inputTree = inputTree;
this.requiresModuleApiPolyfill = requiresModuleApiPolyfill;

// TODO: do we need this?
this.precompile = this.options.templateCompiler.precompile;
Expand All @@ -51,6 +52,7 @@ class TemplateCompiler extends Filter {
processString(string, relativePath) {
let srcDir = this.inputPaths[0];
let srcName = path.join(srcDir, relativePath);

try {
// we have to reverse these for reasons that are a bit bonkers. the initial
// version of this system used `registeredPlugin` from
Expand All @@ -63,25 +65,23 @@ class TemplateCompiler extends Filter {
// sooooooo...... we are forced to maintain that **absolutely bonkers** ordering
let astPlugins = this.options.plugins ? [...this.options.plugins.ast].reverse() : [];

let result =
'export default ' +
utils.template(this.options.templateCompiler, stripBom(string), {
contents: string,
isProduction: this.options.isProduction,
moduleName: relativePath,
parseOptions: {
srcName: srcName,
},

// intentionally not using `plugins: this.options.plugins` here
// because if we do, Ember will mutate the shared plugins object (adding
// all of the built in AST transforms into plugins.ast, which breaks
// persistent caching)
plugins: {
ast: astPlugins,
},
}) +
';';
let precompiled = this.options.templateCompiler.precompile(stripBom(string), {
contents: string,
isProduction: this.options.isProduction,
moduleName: relativePath,
parseOptions: {
srcName: srcName,
},

// intentionally not using `plugins: this.options.plugins` here
// because if we do, Ember will mutate the shared plugins object (adding
// all of the built in AST transforms into plugins.ast, which breaks
// persistent caching)
plugins: {
ast: astPlugins,
},
});

if (this.options.dependencyInvalidation) {
let plugins = pluginsWithDependencies(this.options.plugins.ast);
let dependencies = [];
Expand All @@ -91,7 +91,12 @@ class TemplateCompiler extends Filter {
}
this.dependencies.setDependencies(relativePath, dependencies);
}
return result;

if (this.requiresModuleApiPolyfill) {
return `export default Ember.HTMLBars.template(${precompiled});`;
} else {
return `import { createTemplateFactory } from '@ember/template-factory';\n\nexport default createTemplateFactory(${precompiled});`;
}
} catch (error) {
rethrowBuildError(error);
}
Expand All @@ -106,6 +111,8 @@ class TemplateCompiler extends Filter {
}
}

strippedOptions._requiresModuleApiPolyfill = this.requiresModuleApiPolyfill;

return strippedOptions;
}

Expand Down
34 changes: 11 additions & 23 deletions lib/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,17 +50,20 @@ function isInlinePrecompileBabelPluginRegistered(plugins) {
}

function isColocatedBabelPluginRegistered(plugins) {
return plugins.some(
(plugin) => typeof plugin === 'string' && plugin === require.resolve('./colocated-babel-plugin')
);
return plugins.some((plugin) => {
let path = Array.isArray(plugin) ? plugin[0] : plugin;

return typeof path === 'string' && path === require.resolve('./colocated-babel-plugin');
});
}

function buildParalleizedBabelPlugin(
pluginInfo,
projectConfig,
templateCompilerPath,
isProduction,
customModules
customModules,
requiresModuleApiPolyfill
) {
let parallelBabelInfo = {
requireFile: require.resolve('./require-from-worker'),
Expand All @@ -71,6 +74,7 @@ function buildParalleizedBabelPlugin(
projectConfig,
parallelConfigs: pluginInfo.parallelConfigs,
modules: Object.assign({}, customModules, INLINE_PRECOMPILE_MODULES),
requiresModuleApiPolyfill,
},
};

Expand Down Expand Up @@ -199,12 +203,6 @@ function initializeEmberENV(templateCompiler, EmberENV) {
}
}

function template(templateCompiler, string, options) {
let precompiled = templateCompiler.precompile(string, options);

return 'Ember.HTMLBars.template(' + precompiled + ')';
}

function setup(pluginInfo, options) {
let projectConfig = options.projectConfig || {};
let templateCompilerPath = options.templateCompilerPath;
Expand All @@ -230,18 +228,9 @@ function setup(pluginInfo, options) {
plugins: {
ast: astPlugins,
},
};

for (let option in _options) {
if (option === 'scope') {
// The template compiler expects this option to be named `locals`, but
// we want users to pass it in as `scope`. In the future, we should update
// the template compiler to accept scope as well and remove this.
options.locals = _options.scope;
} else {
options[option] = _options[option];
}
}
..._options,
};

return templatePrecompile(template, options);
};
Expand All @@ -261,7 +250,7 @@ function setup(pluginInfo, options) {
{
precompile,
isProduction: options.isProduction,
ensureModuleApiPolyfill: true,
ensureModuleApiPolyfill: options.requiresModuleApiPolyfill,
modules: Object.assign({}, options.modules, INLINE_PRECOMPILE_MODULES),
},
'ember-cli-htmlbars:inline-precompile',
Expand Down Expand Up @@ -355,7 +344,6 @@ function setupPlugins(wrappers) {
module.exports = {
buildOptions,
initializeEmberENV,
template,
setup,
makeCacheKey,
setupPlugins,
Expand Down
1 change: 1 addition & 0 deletions node-tests/addon-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ describe('ember-cli-htmlbars addon', function () {
project,
parent: project,
ui: this.ui,
_requiresModuleApiPolyfill: true,
});

project.addons.push(this.addon);
Expand Down
Loading

0 comments on commit d92706b

Please sign in to comment.