diff --git a/lib/template-compiler-plugin.js b/lib/template-compiler-plugin.js index 4f9a58c5..dec159e1 100644 --- a/lib/template-compiler-plugin.js +++ b/lib/template-compiler-plugin.js @@ -1,48 +1,14 @@ 'use strict'; -const path = require('path'); -const utils = require('./utils'); const Filter = require('broccoli-persistent-filter'); -const crypto = require('crypto'); -const stringify = require('json-stable-stringify'); -const stripBom = require('strip-bom'); - -function rethrowBuildError(error) { - if (!error) { - throw new Error('Unknown Error'); - } - - if (typeof error === 'string') { - throw new Error('[string exception]: ' + error); - } else { - // augment with location and type information and re-throw. - error.type = 'Template Compiler Error'; - error.location = error.location && error.location.start; - - throw error; - } -} +const jsStringEscape = require('js-string-escape'); class TemplateCompiler extends Filter { - constructor(inputTree, _options, requiresModuleApiPolyfill = true) { - let options = _options || {}; - + constructor(inputTree, options = {}) { if (!('persist' in options)) { options.persist = true; } - super(inputTree, options); - - this.options = options; - this.inputTree = inputTree; - this.requiresModuleApiPolyfill = requiresModuleApiPolyfill; - - // TODO: do we need this? - this.precompile = this.options.templateCompiler.precompile; - - let { templateCompiler, EmberENV } = options; - - utils.initializeEmberENV(templateCompiler, EmberENV); } baseDir() { @@ -50,106 +16,23 @@ 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 - // `ember-template-compiler.js` to set up these plugins (because Ember ~ 1.13 - // only had `registerPlugin`, and there was no way to pass plugins directly - // to the call to `compile`/`precompile`). calling `registerPlugin` - // unfortunately **inverted** the order of plugins (it essentially did - // `PLUGINS = [plugin, ...PLUGINS]`). - // - // sooooooo...... we are forced to maintain that **absolutely bonkers** ordering - let astPlugins = this.options.plugins ? [...this.options.plugins.ast].reverse() : []; - - 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 = []; - for (let i = 0; i < plugins.length; i++) { - let pluginDeps = plugins[i].getDependencies(relativePath); - dependencies = dependencies.concat(pluginDeps); - } - this.dependencies.setDependencies(relativePath, dependencies); - } - - 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); + return [ + `import { hbs } from 'ember-cli-htmlbars';`, + `export default hbs('${jsStringEscape(string)}', { moduleName: '${jsStringEscape( + relativePath + )}' });`, + '', + ].join('\n'); + } + + getDestFilePath(relativePath) { + if (relativePath.endsWith('.hbs')) { + return relativePath.replace(/\.hbs$/, '.js'); } } - - _buildOptionsForHash() { - let strippedOptions = {}; - - for (let key in this.options) { - if (key !== 'templateCompiler') { - strippedOptions[key] = this.options[key]; - } - } - - strippedOptions._requiresModuleApiPolyfill = this.requiresModuleApiPolyfill; - - return strippedOptions; - } - - optionsHash() { - if (!this._optionsHash) { - let templateCompilerCacheKey = utils.getTemplateCompilerCacheKey( - this.options.templateCompilerPath - ); - - this._optionsHash = crypto - .createHash('md5') - .update(stringify(this._buildOptionsForHash()), 'utf8') - .update(templateCompilerCacheKey, 'utf8') - .digest('hex'); - } - - return this._optionsHash; - } - - cacheKeyProcessString(string, relativePath) { - return ( - this.optionsHash() + Filter.prototype.cacheKeyProcessString.call(this, string, relativePath) - ); - } } TemplateCompiler.prototype.extensions = ['hbs', 'handlebars']; TemplateCompiler.prototype.targetExtension = 'js'; -function pluginsWithDependencies(registeredPlugins) { - let found = []; - for (let i = 0; i < registeredPlugins.length; i++) { - if (registeredPlugins[i].getDependencies) { - found.push(registeredPlugins[i]); - } - } - return found; -} - module.exports = TemplateCompiler; diff --git a/lib/utils.js b/lib/utils.js index 66af4d12..aaec2526 100644 --- a/lib/utils.js +++ b/lib/utils.js @@ -190,34 +190,6 @@ function getTemplateCompiler(templateCompilerPath, EmberENV = {}) { return context.module.exports; } -function initializeEmberENV(templateCompiler, EmberENV) { - if (!templateCompiler || !EmberENV) { - return; - } - - let props; - - if (EmberENV.FEATURES) { - props = Object.keys(EmberENV.FEATURES); - - props.forEach((prop) => { - templateCompiler._Ember.FEATURES[prop] = EmberENV.FEATURES[prop]; - }); - } - - if (EmberENV) { - props = Object.keys(EmberENV); - - props.forEach((prop) => { - if (prop === 'FEATURES') { - return; - } - - templateCompiler._Ember.ENV[prop] = EmberENV[prop]; - }); - } -} - function setup(pluginInfo, options) { let projectConfig = options.projectConfig || {}; let templateCompilerPath = options.templateCompilerPath; @@ -374,13 +346,9 @@ function setupPlugins(wrappers) { module.exports = { buildOptions, - initializeEmberENV, setup, - makeCacheKey, setupPlugins, isColocatedBabelPluginRegistered, isInlinePrecompileBabelPluginRegistered, buildParalleizedBabelPlugin, - getTemplateCompiler, - getTemplateCompilerCacheKey, }; diff --git a/node-tests/addon-test.js b/node-tests/addon-test.js index de4b9a4e..5f31f0a1 100644 --- a/node-tests/addon-test.js +++ b/node-tests/addon-test.js @@ -87,8 +87,11 @@ describe('ember-cli-htmlbars addon', function () { yield output.build(); expect(output.read()).to.deep.equal({ - 'hello.js': - 'export default Ember.HTMLBars.template({"id":"pb4oG9l/","block":"[[[10,0],[12],[1,\\"Hello, World!\\"],[13]],[],false,[]]","moduleName":"hello.hbs","isStrictMode":false});', + 'hello.js': [ + `import { hbs } from 'ember-cli-htmlbars';`, + `export default hbs('
Hello, World!
', { moduleName: 'hello.hbs' });`, + '', + ].join('\n'), }); }) ); diff --git a/node-tests/ast_plugins_test.js b/node-tests/ast_plugins_test.js deleted file mode 100644 index 4dd61468..00000000 --- a/node-tests/ast_plugins_test.js +++ /dev/null @@ -1,247 +0,0 @@ -/// @ts-check -'use strict'; - -const path = require('path'); -const assert = require('assert'); -const fs = require('fs'); -const TemplateCompiler = require('../lib/template-compiler-plugin'); -const co = require('co'); -const { createTempDir, createBuilder } = require('broccoli-test-helper'); -const fixturify = require('fixturify'); -const addDependencyTracker = require('../lib/addDependencyTracker'); -const templateCompiler = require('ember-source/dist/ember-template-compiler.js'); - -describe('AST plugins', function () { - const they = it; - this.timeout(10000); - - let input, output, builder, tree, htmlbarsOptions; - - async function clearTreeCache(tree) { - if (tree && tree.processor.processor._cache) { - await tree.processor.processor._cache.clear(); - } - } - - beforeEach( - co.wrap(function* () { - rewriterCallCount = 0; - input = yield createTempDir(); - input.write(fixturify.readSync(`${__dirname}/fixtures`)); - htmlbarsOptions = { - isHTMLBars: true, - templateCompiler: templateCompiler, - templateCompilerPath: require.resolve('ember-source/dist/ember-template-compiler.js'), - }; - }) - ); - - afterEach( - co.wrap(function* () { - yield clearTreeCache(tree); - - if (builder) { - builder.cleanup(); - } - - yield input.dispose(); - - if (output) { - yield output.dispose(); - } - }) - ); - - let rewriterCallCount; - function DivRewriterImpl(env) { - let programStackDepth = 0; - let rewriter = { - name: 'test-div-rewriter', - tagNameFile: undefined, - tagName: 'span', - resetDependencies() { - rewriter.tagNameFile = undefined; - rewriter.tagName = 'span'; - }, - dependencies() { - return rewriter.tagNameFile ? [rewriter.tagNameFile] : []; - }, - visitor: { - Program: { - enter() { - programStackDepth++; - if (programStackDepth === 1) { - let sourceFile = env.meta.moduleName; - let pathInfo = sourceFile && path.parse(sourceFile); - if (pathInfo) { - if (pathInfo.base === 'template.hbs') { - rewriterCallCount++; - } - let tagNameFile = input.path(`${pathInfo.name}.tagname`); - if (fs.existsSync(tagNameFile)) { - let tagName = fs.readFileSync(tagNameFile, 'utf-8').trim(); - rewriter.tagName = tagName; - rewriter.tagNameFile = tagNameFile; - } - } - } - }, - exit() { - programStackDepth--; - }, - }, - ElementNode(node) { - if (node.tag === 'div') { - node.tag = rewriter.tagName; - } - }, - }, - }; - return rewriter; - } - const DivRewriter = addDependencyTracker(DivRewriterImpl, true); - - they( - 'are accepted and used.', - co.wrap(function* () { - htmlbarsOptions.plugins = { - ast: [DivRewriter], - }; - - tree = new TemplateCompiler(input.path(), htmlbarsOptions); - - output = createBuilder(tree); - yield output.build(); - - let templateOutput = output.readText('template.js'); - assert.ok(!templateOutput.match(/div/)); - assert.ok(templateOutput.match(/my-custom-element/)); - assert.strictEqual(rewriterCallCount, 1); - }) - ); - - they( - 'will bust the hot cache if the dependency changes.', - co.wrap(function* () { - Object.assign(htmlbarsOptions, { - plugins: { - ast: [DivRewriter], - }, - dependencyInvalidation: true, - }); - - tree = new TemplateCompiler(input.path(), htmlbarsOptions); - - output = createBuilder(tree); - yield output.build(); - - let templateOutput = output.readText('template.js'); - assert.ok(!templateOutput.match(/div/)); - assert.ok(templateOutput.match(/my-custom-element/)); - assert.strictEqual(rewriterCallCount, 1); - - // The state didn't change. the output should be cached - // and the rewriter shouldn't be invoked. - yield output.build(); - assert.deepStrictEqual(output.changes(), {}); - templateOutput = output.readText('template.js'); - assert.ok(!templateOutput.match(/div/)); - assert.ok(templateOutput.match(/my-custom-element/)); - assert.strictEqual(rewriterCallCount, 1); - - // The state changes. the cache key updates and the template - // should be recompiled. - input.write({ - 'template.tagname': 'MyChangedElement', - }); - yield output.build(); - assert.deepStrictEqual(output.changes(), { - 'template.js': 'change', - 'template.tagname': 'change', - }); - templateOutput = output.readText('template.js'); - assert.strictEqual(rewriterCallCount, 2); - assert.ok(templateOutput.match(/my-changed-element/)); - }) - ); - - describe('with persistent caching enabled', function () { - let forcePersistenceValue; - before(function () { - forcePersistenceValue = process.env.FORCE_PERSISTENCE_IN_CI; - process.env.FORCE_PERSISTENCE_IN_CI = 'true'; - }); - - after(function () { - process.env.FORCE_PERSISTENCE_IN_CI = forcePersistenceValue; - }); - - they( - 'will bust the persistent cache if the template cache key changes.', - co.wrap(function* () { - Object.assign(htmlbarsOptions, { - plugins: { - ast: [DivRewriter], - }, - dependencyInvalidation: true, - }); - - let firstTree, secondTree, thirdTree; - - try { - firstTree = new TemplateCompiler(input.path(), htmlbarsOptions); - - try { - output = createBuilder(firstTree); - yield output.build(); - - let templateOutput = output.readText('template.js'); - assert.ok(!templateOutput.match(/div/)); - assert.ok(templateOutput.match(/my-custom-element/)); - assert.strictEqual(rewriterCallCount, 1); - } finally { - yield output.dispose(); - } - - // The state didn't change. the output should be cached - // and the rewriter shouldn't be invoked. - secondTree = new TemplateCompiler(input.path(), htmlbarsOptions); - try { - let output = createBuilder(secondTree); - yield output.build(); - assert.deepStrictEqual(output.changes()['template.js'], 'create'); - // the "new" file is read from cache. - let templateOutput = output.readText('template.js'); - assert.ok(!templateOutput.match(/div/)); - assert.ok(templateOutput.match(/my-custom-element/)); - assert.strictEqual(rewriterCallCount, 1); - } finally { - yield output.dispose(); - } - - // The state changes. the cache key updates and the template - // should be recompiled. - input.write({ - 'template.tagname': 'MyChangedElement', - }); - - thirdTree = new TemplateCompiler(input.path(), htmlbarsOptions); - try { - let output = createBuilder(thirdTree); - yield output.build(); - let templateOutput = output.readText('template.js'); - assert.strictEqual(rewriterCallCount, 2); - assert.ok(templateOutput.match(/my-changed-element/)); - assert.strictEqual(rewriterCallCount, 2); - } finally { - yield output.dispose(); - } - } finally { - clearTreeCache(firstTree); - clearTreeCache(secondTree); - clearTreeCache(thirdTree); - } - }) - ); - }); -}); diff --git a/node-tests/template_compiler_test.js b/node-tests/template_compiler_test.js index 76bd4601..a853bd8f 100644 --- a/node-tests/template_compiler_test.js +++ b/node-tests/template_compiler_test.js @@ -2,355 +2,42 @@ const assert = require('assert'); const TemplateCompiler = require('../lib/template-compiler-plugin'); -const co = require('co'); const { createTempDir, createBuilder } = require('broccoli-test-helper'); const fixturify = require('fixturify'); -const { stripIndent } = require('common-tags'); +const jsStringEscape = require('js-string-escape'); describe('TemplateCompiler', function () { this.timeout(10000); let input, output, builder; - beforeEach( - co.wrap(function* () { - input = yield createTempDir(); - input.write(fixturify.readSync(`${__dirname}/fixtures`)); - }) - ); - - afterEach( - co.wrap(function* () { - if (builder) { - builder.cleanup(); - } - - yield input.dispose(); - - if (output) { - yield output.dispose(); - } - }) - ); - - let htmlbarsOptions, htmlbarsPrecompile; - - beforeEach(function () { - htmlbarsOptions = { - isHTMLBars: true, - plugins: { - ast: [], - }, - templateCompiler: require('ember-source/dist/ember-template-compiler.js'), - templateCompilerPath: require.resolve('ember-source/dist/ember-template-compiler.js'), - }; - - htmlbarsPrecompile = htmlbarsOptions.templateCompiler.precompile; + beforeEach(async function () { + input = await createTempDir(); + input.write(fixturify.readSync(`${__dirname}/fixtures`)); }); - describe('requiresModuleApiPolyfill: true', function () { - it( - 'precompiles templates into htmlbars', - co.wrap(function* () { - let tree = new TemplateCompiler(input.path(), htmlbarsOptions, true); - - output = createBuilder(tree); - yield output.build(); - - let source = input.readText('template.hbs'); - let expected = `export default Ember.HTMLBars.template(${htmlbarsPrecompile(source, { - moduleName: 'template.hbs', - })});`; - assert.strictEqual(output.readText('template.js'), expected); - }) - ); - - 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, true); - - output = createBuilder(tree); - await output.build(); - - 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, true); - - output = createBuilder(tree); - await output.build(); - - assert.ok(wasProduction); - }); - - it( - 'ignores utf-8 byte order marks', - co.wrap(function* () { - let tree = new TemplateCompiler(input.path(), htmlbarsOptions, true); - - output = createBuilder(tree); - yield output.build(); - - let source = input.readText('template.hbs'); - let expected = `export default Ember.HTMLBars.template(${htmlbarsPrecompile(source, { - moduleName: 'template-with-bom.hbs', - })});`; - - assert.strictEqual(output.readText('template-with-bom.js'), expected); - }) - ); - - it( - 'passes FEATURES to compiler when provided as `FEATURES` [DEPRECATED]', - co.wrap(function* () { - htmlbarsOptions.FEATURES = { - 'ember-htmlbars-component-generation': true, - }; - - let tree = new TemplateCompiler(input.path(), htmlbarsOptions, true); - - output = createBuilder(tree); - yield output.build(); - - let source = input.readText('web-component-template.hbs'); - let expected = `export default Ember.HTMLBars.template(${htmlbarsPrecompile(source, { - moduleName: 'web-component-template.hbs', - })});`; - - assert.strictEqual(output.readText('web-component-template.js'), expected); - }) - ); - - it( - 'passes FEATURES to compiler when provided as `EmberENV.FEATURES`', - co.wrap(function* () { - htmlbarsOptions.EmberENV = { - FEATURES: { - 'ember-htmlbars-component-generation': true, - }, - }; - - let tree = new TemplateCompiler(input.path(), htmlbarsOptions, true); - - output = createBuilder(tree); - yield output.build(); - - let source = input.readText('web-component-template.hbs'); - let expected = `export default Ember.HTMLBars.template(${htmlbarsPrecompile(source, { - moduleName: 'web-component-template.hbs', - })});`; - - assert.strictEqual(output.readText('web-component-template.js'), expected); - }) - ); + afterEach(async function () { + if (builder) { + builder.cleanup(); + } + await input.dispose(); + if (output) { + await output.dispose(); + } }); - describe('requiresModuleApiPolyfill: false', function () { - it( - 'precompiles templates into htmlbars', - co.wrap(function* () { - let tree = new TemplateCompiler(input.path(), htmlbarsOptions, false); - - output = createBuilder(tree); - yield output.build(); - - let source = input.readText('template.hbs'); - let expected = stripIndent` - import { createTemplateFactory } from '@ember/template-factory'; - - export default createTemplateFactory(${htmlbarsPrecompile(source, { - moduleName: 'template.hbs', - })}); - `; - assert.strictEqual(output.readText('template.js'), expected); - }) - ); - - 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, false); - - output = createBuilder(tree); - await output.build(); - - let expected = stripIndent` - import { createTemplateFactory } from '@ember/template-factory'; - - export default createTemplateFactory(${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, false); - - output = createBuilder(tree); - await output.build(); - - assert.ok(wasProduction); - }); - - it( - 'ignores utf-8 byte order marks', - co.wrap(function* () { - let tree = new TemplateCompiler(input.path(), htmlbarsOptions, false); - - output = createBuilder(tree); - yield output.build(); - - let source = input.readText('template.hbs'); - let expected = stripIndent` - import { createTemplateFactory } from '@ember/template-factory'; - - export default createTemplateFactory(${htmlbarsPrecompile(source, { - moduleName: 'template-with-bom.hbs', - })}); - `; - - assert.strictEqual(output.readText('template-with-bom.js'), expected); - }) - ); - - it( - 'passes FEATURES to compiler when provided as `FEATURES` [DEPRECATED]', - co.wrap(function* () { - htmlbarsOptions.FEATURES = { - 'ember-htmlbars-component-generation': true, - }; - - let tree = new TemplateCompiler(input.path(), htmlbarsOptions, false); - - output = createBuilder(tree); - yield output.build(); - - let source = input.readText('web-component-template.hbs'); - let expected = stripIndent` - import { createTemplateFactory } from '@ember/template-factory'; - - export default createTemplateFactory(${htmlbarsPrecompile(source, { - moduleName: 'web-component-template.hbs', - })}); - `; - - assert.strictEqual(output.readText('web-component-template.js'), expected); - }) - ); - - it( - 'passes FEATURES to compiler when provided as `EmberENV.FEATURES`', - co.wrap(function* () { - htmlbarsOptions.EmberENV = { - FEATURES: { - 'ember-htmlbars-component-generation': true, - }, - }; - - let tree = new TemplateCompiler(input.path(), htmlbarsOptions, false); - - output = createBuilder(tree); - yield output.build(); - - let source = input.readText('web-component-template.hbs'); - let expected = stripIndent` - import { createTemplateFactory } from '@ember/template-factory'; + it('converts hbs into JS', async function () { + let tree = new TemplateCompiler(input.path()); - export default createTemplateFactory(${htmlbarsPrecompile(source, { - moduleName: 'web-component-template.hbs', - })}); - `; + output = createBuilder(tree); + await output.build(); - assert.strictEqual(output.readText('web-component-template.js'), expected); - }) - ); + let source = input.readText('template.hbs'); + let expected = [ + `import { hbs } from 'ember-cli-htmlbars';`, + `export default hbs('${jsStringEscape(source)}', { moduleName: 'template.hbs' });`, + '', + ].join('\n'); + assert.strictEqual(output.readText('template.js'), expected); }); }); diff --git a/node-tests/utils_test.js b/node-tests/utils_test.js index b4022454..96c3dd82 100644 --- a/node-tests/utils_test.js +++ b/node-tests/utils_test.js @@ -4,36 +4,6 @@ const utils = require('../lib/utils'); const assert = require('assert'); describe('utils', function () { - let templateCompiler; - - describe('initializeEmberENV', function () { - beforeEach(function () { - templateCompiler = require('ember-source/dist/ember-template-compiler'); - }); - - it('passes other ENV variables to compiler when provided', function () { - let EmberENV = { - FOO_BAR: true, - }; - - utils.initializeEmberENV(templateCompiler, EmberENV); - - assert.strictEqual(templateCompiler._Ember.ENV.FOO_BAR, true); - }); - - it('passes features through when provided', function () { - let EmberENV = { - FEATURES: { - BLAH: true, - }, - }; - - utils.initializeEmberENV(templateCompiler, EmberENV); - - assert.strictEqual(templateCompiler._Ember.FEATURES.BLAH, true); - }); - }); - describe('setupPlugins', function () { it('for 0 plugins', function () { let pluginWrappers = []; diff --git a/package.json b/package.json index 78a81822..4814ddf6 100644 --- a/package.json +++ b/package.json @@ -42,10 +42,9 @@ "fs-tree-diff": "^2.0.1", "hash-for-dep": "^1.5.1", "heimdalljs-logger": "^0.1.10", - "json-stable-stringify": "^1.0.1", + "js-string-escape": "^1.0.1", "semver": "^7.3.4", "silent-error": "^1.1.1", - "strip-bom": "^4.0.0", "walk-sync": "^2.2.0" }, "devDependencies": { diff --git a/yarn.lock b/yarn.lock index d0c7f080..fa3093b4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8241,7 +8241,7 @@ jquery@^3.5.1: js-string-escape@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/js-string-escape/-/js-string-escape-1.0.1.tgz#e2625badbc0d67c7533e9edc1068c587ae4137ef" - integrity sha1-4mJbrbwNZ8dTPp7cEGjFh65BN+8= + integrity sha512-Smw4xcfIQ5LVjAOuJCvN/zIodzA/BBSsluuoSykP+lUvScIi4U6RJLfwHet5cxFnCswUjISV8oAXaqaJDY3chg== "js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: version "4.0.0"