diff --git a/lib/ember-addon-main.js b/lib/ember-addon-main.js index 18687f09..d4b555ab 100644 --- a/lib/ember-addon-main.js +++ b/lib/ember-addon-main.js @@ -61,6 +61,7 @@ module.exports = { // Please coordinate with @chriseppstein if you need to change it. transpileTree(inputTree, htmlbarsOptions) { const TemplateCompiler = require('./template-compiler-plugin'); + return new TemplateCompiler(inputTree, htmlbarsOptions); }, @@ -68,6 +69,8 @@ module.exports = { // ensure that broccoli-ember-hbs-template-compiler is not processing hbs files registry.remove('template', 'broccoli-ember-hbs-template-compiler'); + let isProduction = process.env.EMBER_ENV === 'production'; + // when this.parent === this.project, `this.parent.name` is a function 😭 let parentName = typeof this.parent.name === 'function' ? this.parent.name() : this.parent.name; @@ -90,14 +93,26 @@ module.exports = { inputTree = debugTree(new ColocatedTemplateProcessor(inputTree), '02-colocated-output'); } + this._addon.logger.debug(`setup *.hbs compiler with ${htmlbarsOptions.pluginNames}`); - return debugTree(this._addon.transpileTree(inputTree, htmlbarsOptions), '03-output'); + return debugTree( + this._addon.transpileTree(inputTree, { + isProduction, + ...htmlbarsOptions, + }), + '03-output' + ); }, - precompile(string, options) { + precompile(string, _options) { + let options = _options; let htmlbarsOptions = this._addon.htmlbarsOptions(); let templateCompiler = htmlbarsOptions.templateCompiler; + if (isProduction) { + options = Object.assign({ isProduction }, _options); + } + return utils.template(templateCompiler, string, options); }, }); @@ -152,6 +167,8 @@ module.exports = { addonOptions.babel.plugins = addonOptions.babel.plugins || []; let babelPlugins = addonOptions.babel.plugins; + let isProduction = process.env.EMBER_ENV === 'production'; + // add the babel-plugin-htmlbars-inline-precompile to the list of plugins // used by `ember-cli-babel` addon if (!utils.isInlinePrecompileBabelPluginRegistered(babelPlugins)) { @@ -166,7 +183,8 @@ module.exports = { let htmlbarsInlinePrecompilePlugin = utils.buildParalleizedBabelPlugin( pluginInfo, this.projectConfig(), - templateCompilerPath + templateCompilerPath, + isProduction ); babelPlugins.push(htmlbarsInlinePrecompilePlugin); @@ -177,6 +195,7 @@ module.exports = { this.logger.debug('Prevented by these plugins: ' + pluginInfo.unparallelizableWrappers); let htmlBarsPlugin = utils.setup(pluginInfo, { + isProduction, projectConfig: this.projectConfig(), templateCompilerPath, }); diff --git a/lib/template-compiler-plugin.js b/lib/template-compiler-plugin.js index 2b395db7..4beb2d80 100644 --- a/lib/template-compiler-plugin.js +++ b/lib/template-compiler-plugin.js @@ -71,6 +71,7 @@ class TemplateCompiler extends Filter { 'export default ' + utils.template(this.options.templateCompiler, stripBom(string), { contents: string, + isProduction: this.options.isProduction, moduleName: relativePath, parseOptions: { srcName: srcName, diff --git a/lib/utils.js b/lib/utils.js index cc7ff064..a5399e45 100644 --- a/lib/utils.js +++ b/lib/utils.js @@ -47,12 +47,18 @@ function isColocatedBabelPluginRegistered(plugins) { ); } -function buildParalleizedBabelPlugin(pluginInfo, projectConfig, templateCompilerPath) { +function buildParalleizedBabelPlugin( + pluginInfo, + projectConfig, + templateCompilerPath, + isProduction +) { let parallelBabelInfo = { requireFile: require.resolve('./require-from-worker'), buildUsing: 'build', params: { templateCompilerPath, + isProduction, projectConfig, parallelConfigs: pluginInfo.parallelConfigs, modules: INLINE_PRECOMPILE_MODULES, @@ -179,6 +185,7 @@ function initializeEmberENV(templateCompiler, EmberENV) { function template(templateCompiler, string, options) { let precompiled = templateCompiler.precompile(string, options); + return 'Ember.HTMLBars.template(' + precompiled + ')'; } @@ -201,7 +208,7 @@ function setup(pluginInfo, options) { let plugin = [ require.resolve('babel-plugin-htmlbars-inline-precompile'), - { precompile, modules: INLINE_PRECOMPILE_MODULES }, + { precompile, isProduction: options.isProduction, modules: INLINE_PRECOMPILE_MODULES }, 'ember-cli-htmlbars:inline-precompile', ]; diff --git a/node-tests/template_compiler_test.js b/node-tests/template_compiler_test.js index 66ea10d0..3f47d583 100644 --- a/node-tests/template_compiler_test.js +++ b/node-tests/template_compiler_test.js @@ -37,6 +37,9 @@ describe('TemplateCompiler', function () { beforeEach(function () { htmlbarsOptions = { isHTMLBars: true, + plugins: { + ast: [], + }, templateCompiler: require('ember-source/dist/ember-template-compiler.js'), }; @@ -59,6 +62,78 @@ describe('TemplateCompiler', function () { }) ); + it('invokes AST plugins', async function () { + let source = '{{foo-bar}}'; + input.write({ + 'template.hbs': source, + }); + let plugin = (env) => { + return { + name: 'fake-ast-plugin', + + visitor: { + MustacheStatement() { + return env.syntax.builders.text('Huzzah!'); + }, + }, + }; + }; + + htmlbarsOptions.plugins.ast.push(plugin); + + let tree = new TemplateCompiler(input.path(), htmlbarsOptions); + + try { + output = createBuilder(tree); + await output.build(); + } finally { + tree.unregisterPlugins(); + } + + let expected = `export default Ember.HTMLBars.template(${htmlbarsPrecompile(source, { + moduleName: 'template.hbs', + plugins: { + ast: [plugin], + }, + })});`; + + let outputString = output.readText('template.js'); + assert.strictEqual(outputString, expected); + assert.ok(outputString.includes('Huzzah!')); + }); + + it('AST Plugins have access to `isProduction` status', async function () { + let source = '{{foo-bar}}'; + input.write({ + 'template.hbs': source, + }); + + let wasProduction = false; + let plugin = (env) => { + wasProduction = env.isProduction; + + return { + name: 'fake-ast-plugin', + + visitor: {}, + }; + }; + + htmlbarsOptions.isProduction = true; + htmlbarsOptions.plugins.ast.push(plugin); + + let tree = new TemplateCompiler(input.path(), htmlbarsOptions); + + try { + output = createBuilder(tree); + await output.build(); + } finally { + tree.unregisterPlugins(); + } + + assert.ok(wasProduction); + }); + it( 'ignores utf-8 byte order marks', co.wrap(function* () { diff --git a/package.json b/package.json index e9865166..4c582f6c 100644 --- a/package.json +++ b/package.json @@ -33,7 +33,7 @@ }, "dependencies": { "@ember/edition-utils": "^1.2.0", - "babel-plugin-htmlbars-inline-precompile": "^4.1.0", + "babel-plugin-htmlbars-inline-precompile": "^4.2.0", "broccoli-debug": "^0.6.5", "broccoli-persistent-filter": "^3.1.0", "broccoli-plugin": "^4.0.3", diff --git a/yarn.lock b/yarn.lock index 213c78c4..50b487bf 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2131,10 +2131,10 @@ babel-plugin-htmlbars-inline-precompile@^1.0.0: resolved "https://registry.yarnpkg.com/babel-plugin-htmlbars-inline-precompile/-/babel-plugin-htmlbars-inline-precompile-1.0.0.tgz#a9d2f6eaad8a3f3d361602de593a8cbef8179c22" integrity sha512-4jvKEHR1bAX03hBDZ94IXsYCj3bwk9vYsn6ux6JZNL2U5pvzCWjqyrGahfsGNrhERyxw8IqcirOi9Q6WCo3dkQ== -babel-plugin-htmlbars-inline-precompile@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/babel-plugin-htmlbars-inline-precompile/-/babel-plugin-htmlbars-inline-precompile-4.1.0.tgz#11796422e65d900a968481fa3fb37e0425c928dd" - integrity sha512-gM+UP6HO5RlGiOQzJVGRUHgAsefJeOdh5Pn+rZRS6Tr1MnEqVgTJ2G2ywnl+G+Zcuec18fz7XA+O2tHhsmct6w== +babel-plugin-htmlbars-inline-precompile@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/babel-plugin-htmlbars-inline-precompile/-/babel-plugin-htmlbars-inline-precompile-4.2.0.tgz#73e7a199c14db139b9c9aea240e03b7112784c81" + integrity sha512-n2jMGcFKvubnYi8Ink7zJnC+aQor97v5FJKYUOUKijj5gIDy/sOIAZ7BxDWb0co1VzZokdN7tvtLnQtiWfD1Gw== babel-plugin-module-resolver@^3.1.1: version "3.2.0" @@ -7703,7 +7703,8 @@ mocha@^8.1.0: yargs-unparser "1.6.1" "module-name-inliner@link:./tests/dummy/lib/module-name-inliner": - version "0.1.0" + version "0.0.0" + uid "" morgan@^1.9.1: version "1.9.1"