UNPKG

4.76 kBJavaScriptView Raw
1/* jshint node: true */
2'use strict';
3
4var path = require('path');
5var fs = require('fs');
6var hashForDep = require('hash-for-dep');
7var HTMLBarsInlinePrecompilePlugin = require('babel-plugin-htmlbars-inline-precompile');
8var SilentError = require('silent-error');
9var resolve = require('resolve');
10var semver = require('semver');
11
12module.exports = {
13 name: 'ember-cli-htmlbars-inline-precompile',
14
15 init() {
16 this._super.init && this._super.init.apply(this, arguments);
17
18 let babelPath = resolve.sync('ember-cli-babel/package.json', { basedir: this.parent.root });
19 let babelVersion = require(babelPath).version;
20
21 var hasCorrectBabelVersion = semver.lt(babelVersion, '6.0.0-alpha.1');
22
23 if (!hasCorrectBabelVersion) {
24 throw new SilentError('ember-cli-htmlbars-inline-precompile@0.3 requires the host to use ember-cli-babel@5. To use ember-cli-babel@6 please upgrade ember-cli-htmlbars-inline-precompile to 0.4.');
25 }
26 },
27
28 setupPreprocessorRegistry: function(type, registry) {
29 if (type === 'parent') {
30 this.parentRegistry = registry;
31 }
32 },
33
34 included: function(app) {
35 this._super.included(app);
36
37 var emberCLIHtmlBars = this.project.findAddonByName('ember-cli-htmlbars');
38
39 if(emberCLIHtmlBars && emberCLIHtmlBars.inlinePrecompilerRegistered) {
40 return;
41 }
42
43 app.options = app.options || {};
44 app.options.babel = app.options.babel || {};
45 app.options.babel.plugins = app.options.babel.plugins || [];
46
47 // borrowed from ember-cli-htmlbars http://git.io/vJDrW
48 var projectConfig = this.projectConfig() || {};
49 var EmberENV = projectConfig.EmberENV || {};
50 var templateCompilerPath = this.templateCompilerPath();
51
52 // ensure we get a fresh templateCompilerModuleInstance per ember-addon
53 // instance NOTE: this is a quick hack, and will only work as long as
54 // templateCompilerPath is a single file bundle
55 //
56 // (╯°□°)╯︵ ɹǝqɯǝ
57 //
58 // we will also fix this in ember for future releases
59 delete require.cache[templateCompilerPath];
60
61 var clonedEmberENV = JSON.parse(JSON.stringify(EmberENV));
62 global.EmberENV = clonedEmberENV;
63
64 var pluginInfo = this.astPlugins();
65 var Compiler = require(templateCompilerPath);
66 var templateCompilerFullPath = require.resolve(templateCompilerPath);
67 var templateCompilerCacheKey = fs.readFileSync(templateCompilerFullPath, { encoding: 'utf-8' });
68
69 pluginInfo.plugins.forEach(function(plugin) {
70 Compiler.registerPlugin('ast', plugin);
71 });
72
73 var PrecompileInlineHTMLBarsPlugin = HTMLBarsInlinePrecompilePlugin(Compiler.precompile, {
74 cacheKey: [templateCompilerCacheKey].concat(pluginInfo.cacheKeys).join('|')
75 });
76
77 delete require.cache[templateCompilerPath];
78 delete global.Ember;
79 delete global.EmberENV;
80
81 // add the HTMLBarsInlinePrecompilePlugin to the list of plugins used by
82 // the `ember-cli-babel` addon
83 if (!this._registeredWithBabel) {
84 app.options.babel.plugins.push(PrecompileInlineHTMLBarsPlugin);
85 this._registeredWithBabel = true;
86 }
87 },
88
89 // from ember-cli-htmlbars :(
90 astPlugins: function() {
91 var pluginWrappers = this.parentRegistry.load('htmlbars-ast-plugin');
92 var plugins = [];
93 var cacheKeys = [];
94
95 for (var i = 0; i < pluginWrappers.length; i++) {
96 var wrapper = pluginWrappers[i];
97
98 plugins.push(wrapper.plugin);
99
100 if (typeof wrapper.baseDir === 'function') {
101 var pluginHashForDep = hashForDep(wrapper.baseDir());
102 cacheKeys.push(pluginHashForDep);
103 } else {
104 // support for ember-cli < 2.2.0
105 var log = this.ui.writeDeprecateLine || this.ui.writeLine;
106
107 log.call(this.ui, 'ember-cli-htmlbars-inline-precompile is opting out of caching due to an AST plugin that does not provide a caching strategy: `' + wrapper.name + '`.');
108 cacheKeys.push((new Date()).getTime() + '|' + Math.random());
109 }
110 }
111
112 return {
113 plugins: plugins,
114 cacheKeys: cacheKeys
115 };
116 },
117
118 // borrowed from ember-cli-htmlbars http://git.io/vJDrW
119 projectConfig: function () {
120 return this.project.config(process.env.EMBER_ENV);
121 },
122
123 // borrowed from ember-cli-htmlbars http://git.io/vJDrw
124 templateCompilerPath: function() {
125 var config = this.projectConfig();
126 var templateCompilerPath = config['ember-cli-htmlbars'] && config['ember-cli-htmlbars'].templateCompilerPath;
127
128 var ember = this.project.findAddonByName('ember-source');
129 if (ember) {
130 return ember.absolutePaths.templateCompiler;
131 } else if (!templateCompilerPath) {
132 templateCompilerPath = this.project.bowerDirectory + '/ember/ember-template-compiler';
133 }
134
135 return path.resolve(this.project.root, templateCompilerPath);
136 }
137};