|
1 | 1 | 'use strict';
|
2 | 2 |
|
3 |
| -const path = require('path'); |
4 |
| -const utils = require('./utils'); |
5 | 3 | const Filter = require('broccoli-persistent-filter');
|
6 |
| -const crypto = require('crypto'); |
7 |
| -const stringify = require('json-stable-stringify'); |
8 |
| -const stripBom = require('strip-bom'); |
9 |
| - |
10 |
| -function rethrowBuildError(error) { |
11 |
| - if (!error) { |
12 |
| - throw new Error('Unknown Error'); |
13 |
| - } |
14 |
| - |
15 |
| - if (typeof error === 'string') { |
16 |
| - throw new Error('[string exception]: ' + error); |
17 |
| - } else { |
18 |
| - // augment with location and type information and re-throw. |
19 |
| - error.type = 'Template Compiler Error'; |
20 |
| - error.location = error.location && error.location.start; |
21 |
| - |
22 |
| - throw error; |
23 |
| - } |
24 |
| -} |
| 4 | +const jsStringEscape = require('js-string-escape'); |
25 | 5 |
|
26 | 6 | class TemplateCompiler extends Filter {
|
27 |
| - constructor(inputTree, _options, requiresModuleApiPolyfill = true) { |
28 |
| - let options = _options || {}; |
29 |
| - |
| 7 | + constructor(inputTree, options = {}) { |
30 | 8 | if (!('persist' in options)) {
|
31 | 9 | options.persist = true;
|
32 | 10 | }
|
33 |
| - |
34 | 11 | super(inputTree, options);
|
35 |
| - |
36 |
| - this.options = options; |
37 |
| - this.inputTree = inputTree; |
38 |
| - this.requiresModuleApiPolyfill = requiresModuleApiPolyfill; |
39 |
| - |
40 |
| - // TODO: do we need this? |
41 |
| - this.precompile = this.options.templateCompiler.precompile; |
42 |
| - |
43 |
| - let { templateCompiler, EmberENV } = options; |
44 |
| - |
45 |
| - utils.initializeEmberENV(templateCompiler, EmberENV); |
46 | 12 | }
|
47 | 13 |
|
48 | 14 | baseDir() {
|
49 | 15 | return __dirname;
|
50 | 16 | }
|
51 | 17 |
|
52 | 18 | processString(string, relativePath) {
|
53 |
| - let srcDir = this.inputPaths[0]; |
54 |
| - let srcName = path.join(srcDir, relativePath); |
55 |
| - |
56 |
| - try { |
57 |
| - // we have to reverse these for reasons that are a bit bonkers. the initial |
58 |
| - // version of this system used `registeredPlugin` from |
59 |
| - // `ember-template-compiler.js` to set up these plugins (because Ember ~ 1.13 |
60 |
| - // only had `registerPlugin`, and there was no way to pass plugins directly |
61 |
| - // to the call to `compile`/`precompile`). calling `registerPlugin` |
62 |
| - // unfortunately **inverted** the order of plugins (it essentially did |
63 |
| - // `PLUGINS = [plugin, ...PLUGINS]`). |
64 |
| - // |
65 |
| - // sooooooo...... we are forced to maintain that **absolutely bonkers** ordering |
66 |
| - let astPlugins = this.options.plugins ? [...this.options.plugins.ast].reverse() : []; |
67 |
| - |
68 |
| - let precompiled = this.options.templateCompiler.precompile(stripBom(string), { |
69 |
| - contents: string, |
70 |
| - isProduction: this.options.isProduction, |
71 |
| - moduleName: relativePath, |
72 |
| - parseOptions: { |
73 |
| - srcName: srcName, |
74 |
| - }, |
75 |
| - |
76 |
| - // intentionally not using `plugins: this.options.plugins` here |
77 |
| - // because if we do, Ember will mutate the shared plugins object (adding |
78 |
| - // all of the built in AST transforms into plugins.ast, which breaks |
79 |
| - // persistent caching) |
80 |
| - plugins: { |
81 |
| - ast: astPlugins, |
82 |
| - }, |
83 |
| - }); |
84 |
| - |
85 |
| - if (this.options.dependencyInvalidation) { |
86 |
| - let plugins = pluginsWithDependencies(this.options.plugins.ast); |
87 |
| - let dependencies = []; |
88 |
| - for (let i = 0; i < plugins.length; i++) { |
89 |
| - let pluginDeps = plugins[i].getDependencies(relativePath); |
90 |
| - dependencies = dependencies.concat(pluginDeps); |
91 |
| - } |
92 |
| - this.dependencies.setDependencies(relativePath, dependencies); |
93 |
| - } |
94 |
| - |
95 |
| - if (this.requiresModuleApiPolyfill) { |
96 |
| - return `export default Ember.HTMLBars.template(${precompiled});`; |
97 |
| - } else { |
98 |
| - return `import { createTemplateFactory } from '@ember/template-factory';\n\nexport default createTemplateFactory(${precompiled});`; |
99 |
| - } |
100 |
| - } catch (error) { |
101 |
| - rethrowBuildError(error); |
| 19 | + return [ |
| 20 | + `import { hbs } from 'ember-cli-htmlbars';`, |
| 21 | + `export default hbs('${jsStringEscape(string)}', { moduleName: '${jsStringEscape( |
| 22 | + relativePath |
| 23 | + )}' });`, |
| 24 | + '', |
| 25 | + ].join('\n'); |
| 26 | + } |
| 27 | + |
| 28 | + getDestFilePath(relativePath) { |
| 29 | + if (relativePath.endsWith('.hbs')) { |
| 30 | + return relativePath.replace(/\.hbs$/, '.js'); |
102 | 31 | }
|
103 | 32 | }
|
104 |
| - |
105 |
| - _buildOptionsForHash() { |
106 |
| - let strippedOptions = {}; |
107 |
| - |
108 |
| - for (let key in this.options) { |
109 |
| - if (key !== 'templateCompiler') { |
110 |
| - strippedOptions[key] = this.options[key]; |
111 |
| - } |
112 |
| - } |
113 |
| - |
114 |
| - strippedOptions._requiresModuleApiPolyfill = this.requiresModuleApiPolyfill; |
115 |
| - |
116 |
| - return strippedOptions; |
117 |
| - } |
118 |
| - |
119 |
| - optionsHash() { |
120 |
| - if (!this._optionsHash) { |
121 |
| - let templateCompilerCacheKey = utils.getTemplateCompilerCacheKey( |
122 |
| - this.options.templateCompilerPath |
123 |
| - ); |
124 |
| - |
125 |
| - this._optionsHash = crypto |
126 |
| - .createHash('md5') |
127 |
| - .update(stringify(this._buildOptionsForHash()), 'utf8') |
128 |
| - .update(templateCompilerCacheKey, 'utf8') |
129 |
| - .digest('hex'); |
130 |
| - } |
131 |
| - |
132 |
| - return this._optionsHash; |
133 |
| - } |
134 |
| - |
135 |
| - cacheKeyProcessString(string, relativePath) { |
136 |
| - return ( |
137 |
| - this.optionsHash() + Filter.prototype.cacheKeyProcessString.call(this, string, relativePath) |
138 |
| - ); |
139 |
| - } |
140 | 33 | }
|
141 | 34 |
|
142 | 35 | TemplateCompiler.prototype.extensions = ['hbs', 'handlebars'];
|
143 | 36 | TemplateCompiler.prototype.targetExtension = 'js';
|
144 | 37 |
|
145 |
| -function pluginsWithDependencies(registeredPlugins) { |
146 |
| - let found = []; |
147 |
| - for (let i = 0; i < registeredPlugins.length; i++) { |
148 |
| - if (registeredPlugins[i].getDependencies) { |
149 |
| - found.push(registeredPlugins[i]); |
150 |
| - } |
151 |
| - } |
152 |
| - return found; |
153 |
| -} |
154 |
| - |
155 | 38 | module.exports = TemplateCompiler;
|
0 commit comments