Skip to content

Commit

Permalink
feature: now use Handlebars for building the index.html. (#712)
Browse files Browse the repository at this point in the history
  • Loading branch information
hansl committed May 10, 2016
1 parent 7ba388d commit d81e4b1
Show file tree
Hide file tree
Showing 7 changed files with 108 additions and 104 deletions.
10 changes: 5 additions & 5 deletions addon/ng2/blueprints/ng2/files/__path__/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@
<meta charset="utf-8">
<title><%= jsComponentName %></title>
<base href="/">
{{content-for 'head'}}

{{#unless environment.production}}
<script src="/angular-cli-live-reload.js" type="text/javascript"></script>
{{/unless}}
<link rel="icon" type="image/x-icon" href="favicon.ico"><% if (isMobile) { %>
<link rel="manifest" href="/manifest.webapp"><% } %>
<meta name="viewport" content="width=device-width, initial-scale=1">
Expand All @@ -24,10 +27,7 @@
<body>
<<%= htmlComponentName %>-app>Loading...</<%= htmlComponentName %>-app>

<script src="vendor/es6-shim/es6-shim.js"></script>
<script src="vendor/reflect-metadata/Reflect.js"></script>
<script src="vendor/systemjs/dist/system.src.js"></script>
<script src="vendor/zone.js/dist/zone.js"></script>
{{#each scripts.polyfills}}<script src="{{.}}"></script>{{/each}}

<script>
System.import('system-config.js').then(function () {
Expand Down
54 changes: 29 additions & 25 deletions lib/broccoli/angular2-app.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,35 +2,34 @@
const path = require('path');
const fs = require('fs');

const isProduction = require('./is-production');
const BroccoliPlugin = require('broccoli-writer');
const BroccoliConfigReplace = require('./broccoli-config-replace');
const BroccoliTypescript = require('./broccoli-typescript');
const BundlePlugin = require('./angular-broccoli-bundle');
const BroccoliFunnel = require('broccoli-funnel');
const BroccoliMergeTrees = require('broccoli-merge-trees');
const BroccoliSource = require('broccoli-source');
const UnwatchedDir = BroccoliSource.UnwatchedDir;
const Project = require('ember-cli/lib/models/project');
const HandlebarReplace = require('./broccoli-handlebars');
const config = require('../../addon/ng2/models/config');
const loadEnvironment = require('./environment');

class Angular2App extends BroccoliPlugin {
constructor(project, inputNode, options) {
const ngConfig = config.CliConfig.fromProject();
super();
this.ngConfig = config.CliConfig.fromProject();

if (!options) {
options = inputNode;
inputNode = null;
}

super();
options = options || {};

this._options = options;
this._sourceDir = options.sourceDir
|| (ngConfig.defaults && ngConfig.defaults.sourceDir)
|| (this.ngConfig.defaults && this.ngConfig.defaults.sourceDir)
|| 'src';
this._inputNode = inputNode || this._buildInputTree();
this._destDir = options.destDir || '';

// By default, add all spec files to the tsCompiler.
Expand All @@ -40,6 +39,7 @@ class Angular2App extends BroccoliPlugin {

this._initProject();
this._notifyAddonIncluded();
this._inputNode = inputNode || this._buildInputTree();

this._tree = this._buildTree();
}
Expand Down Expand Up @@ -135,7 +135,7 @@ class Angular2App extends BroccoliPlugin {

var merged = new BroccoliMergeTrees(buildTrees, { overwrite: true });

if (isProduction) {
if (loadEnvironment(this.project).production) {
merged = this._getBundleTree(merged);
}

Expand Down Expand Up @@ -216,7 +216,6 @@ class Angular2App extends BroccoliPlugin {
case 'config-module': this._contentForConfigModule(content, config); break;
case 'app-boot': this._contentForAppBoot(content, config); break;
}*/

content = this.project.addons.reduce(function (content, addon) {
var addonContent = addon.contentFor ? addon.contentFor(type) : null;
if (addonContent) {
Expand All @@ -226,22 +225,9 @@ class Angular2App extends BroccoliPlugin {
return content;
}, content);


return content.join('\n');
}

/**
* @private
* @method _getReplacePatterns
* @return Array<Pattern> Replace patterns.
*/
_getReplacePatterns() {
return [{
match: /\{\{content-for ['"](.+)["']\}\}/g,
replacement: isProduction ? '' : this._contentFor.bind(this)
}];
}

/**
* Returns the tree for app/index.html.
*
Expand All @@ -264,9 +250,26 @@ class Angular2App extends BroccoliPlugin {
}
});

return BroccoliConfigReplace(indexTree, {
files: files,
patterns: this._getReplacePatterns()
return new HandlebarReplace(indexTree, {
config: this.ngConfig,
environment: loadEnvironment(this.project),
scripts: {
polyfills: this._options.polyfills || [
'vendor/es6-shim/es6-shim.js',
'vendor/reflect-metadata/Reflect.js',
'vendor/systemjs/dist/system.src.js',
'vendor/zone.js/dist/zone.js'
]
}
}, {
helpers: {
'content-for': (name) => {
// TODO: remove content-for.
// eslint-disable-next-line no-console
console.warn('"{{content-for}}" has been deprecated and will be removed before RC.');
return this._contentFor(null, name);
}
}
});
}

Expand All @@ -284,7 +287,7 @@ class Angular2App extends BroccoliPlugin {
var tsTreeExcludes = ['*.d.ts', 'tsconfig.json'];
var excludeSpecFiles = '**/*.spec.*';

if (isProduction) {
if (loadEnvironment(this.project).production) {
tsTreeExcludes.push(excludeSpecFiles);
}

Expand Down Expand Up @@ -350,6 +353,7 @@ class Angular2App extends BroccoliPlugin {
* @return {Tree} The config files tree.
*/
_getConfigTree() {
const isProduction = loadEnvironment(this.project).production;
var envConfigFile = isProduction ? 'environment.prod.ts' : 'environment.dev.ts';

return new BroccoliFunnel('config', {
Expand Down
71 changes: 0 additions & 71 deletions lib/broccoli/broccoli-config-replace.js

This file was deleted.

37 changes: 37 additions & 0 deletions lib/broccoli/broccoli-handlebars.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
'use strict';

const fs = require('fs-extra');
const path = require('path');
const BroccoliCacheWriter = require('broccoli-caching-writer');
const Handlebars = require('handlebars');


class HandlebarReplace extends BroccoliCacheWriter {
constructor(inputTree, context, options) {
super([inputTree], options);
if (options && options.helpers) {
Object.keys(options.helpers).forEach((helperName) => {
Handlebars.registerHelper(helperName, function() {
const result = options.helpers[helperName].apply(null, arguments);
return new Handlebars.SafeString(result);
});
})
}
this._context = context;
}

build() {
this.listFiles().forEach((filePath) => {
const destPath = filePath.replace(this.inputPaths[0], this.outputPath);
const content = fs.readFileSync(filePath, 'utf-8');
const template = Handlebars.compile(content);

if (!fs.existsSync(path.dirname(destPath))) {
fs.mkdirsSync(path.dirname(destPath));
}
fs.writeFileSync(destPath, template(this._context), 'utf-8');
});
}
}

module.exports = HandlebarReplace;
28 changes: 28 additions & 0 deletions lib/broccoli/environment.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
'use strict';
// Load the environment file defined by the EMBER_ENV environment variable.
const fs = require('fs');
const path = require('path');
const ts = require('typescript');


// Export the content of the transpiled file.
module.exports = function loadEnvironment(project, environment) {
let env = environment || process.env['EMBER_ENV'] || 'dev';
switch (env) {
case 'production': env = 'prod'; break;
case 'development': env = 'dev'; break;
}

// Load the content of the environment file.
const filePath = path.join(project.root, `config/environment.${env}.ts`);
const source = fs.readFileSync(filePath, 'utf-8');
const result = ts.transpile(source, {
target: ts.ScriptTarget.ES5,
module: ts.ModuleKind.CommonJs
});

const Module = module.constructor;
const m = new Module();
m._compile(result, filePath);
return m.exports.environment;
};
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
"exit": "^0.1.2",
"fs-extra": "^0.30.0",
"glob": "^7.0.3",
"handlebars": "^4.0.5",
"leek": "0.0.21",
"lodash": "^4.11.1",
"opn": "4.0.1",
Expand Down
11 changes: 8 additions & 3 deletions tests/e2e/e2e_workflow.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -76,15 +76,20 @@ describe('Basic end-to-end Workflow', function () {
this.timeout(420000);

return ng(['build', '--silent'])
.catch(() => {
throw new Error('Build failed.');
})
.then(function () {
expect(existsSync(path.join(process.cwd(), 'dist'))).to.be.equal(true);

// Check the index.html to have no handlebar tokens in it.
const indexHtml = fs.readFileSync(path.join(process.cwd(), 'dist/index.html'), 'utf-8');
expect(indexHtml).to.not.include('{{');
expect(indexHtml).to.include('vendor/es6-shim/es6-shim.js');
})
.then(function () {
// Also does not create new things in GIT.
expect(sh.exec('git status --porcelain').output).to.be.equal(undefined);
})
.catch(() => {
throw new Error('Build failed.');
});
});

Expand Down

0 comments on commit d81e4b1

Please sign in to comment.