Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
fbda2e0
Initial spike of co-located templates RFC.
chancancode May 9, 2019
764615e
Use globals for now
chancancode Aug 10, 2019
a640658
Fix addon compilation
chancancode Aug 12, 2019
4c6017b
Better error for missing default export
chancancode Aug 13, 2019
942c301
v3.2.0-alpha.0
chancancode Aug 22, 2019
66dff2f
Fix some Node 8 issues
chancancode Aug 24, 2019
b9295c5
Fix lint
chancancode Aug 24, 2019
6b5a4d6
Extract ColocatedTemplateProcessor to dedicated file.
Sep 5, 2019
10e5f31
Merge remote-tracking branch 'origin/master' into colocation
Sep 5, 2019
3aabb50
Update linting config to allow async functions.
Sep 5, 2019
d7a579b
Add broccoli-debug logging.
Sep 5, 2019
f7f3f47
Start fleshing out basic testing infrastructure.
Sep 5, 2019
1dbfb87
Merge remote-tracking branch 'origin/master' into colocation
Sep 5, 2019
6ba80f4
Merge remote-tracking branch 'origin/master' into colocation
Sep 9, 2019
24e8ad6
yarn lint:js --fix
Sep 9, 2019
fb2808a
Extract helper method to build merged component JS contents.
Sep 5, 2019
f5a0b01
Add TODO comments for additional tasks.
Sep 6, 2019
6de52e5
Flesh out more tests.
Sep 6, 2019
5709c0f
Avoid adding the import for setComponentTemplate.
Sep 6, 2019
b44e14b
yarn lint:js --fix
Sep 9, 2019
bb4ad58
Fix colocated-broccoli-plugin tests
Sep 9, 2019
9362a4c
Add babel plugin to add setComponentTemplate usage.
Sep 9, 2019
952287b
Simplify implementation / reduce duplication.
Sep 9, 2019
cfa93e3
Make requires more lazy.
Sep 9, 2019
eba43a7
Add proper guard for using colocation.
Sep 9, 2019
99ac97d
Refactor registry toTree setup.
Sep 9, 2019
60b8ae9
Tweak comments in colocated-broccoli-plugin.
Sep 9, 2019
2d58f11
Ensure debugTree's are not "merged" for different invocations.
Sep 9, 2019
9972294
Add tests for scoped addons.
Sep 9, 2019
db7e5f2
Only process colocated files from <app-or-addon-name>/components/
Sep 9, 2019
1ef7d42
Merge pull request #280 from rwjblue/colocation-refactor
Sep 14, 2019
791bde4
Fix setComponentTemplate argument ordering for native classes.
Sep 14, 2019
253503f
Only opt-in to colocation when using octane edition.
Sep 15, 2019
35b66bf
Merge remote-tracking branch 'origin/master' into colocation
Sep 23, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
117 changes: 111 additions & 6 deletions ember-addon-main.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,110 @@
'use strict';

const fs = require('fs');
const path = require('path');
const utils = require('./utils');
const addDependencyTracker = require("./addDependencyTracker");
const hashForDep = require('hash-for-dep');
const walkSync = require('walk-sync');
const Plugin = require('broccoli-plugin');

class ColocatedTemplateProcessor extends Plugin {
Comment thread
rwjblue marked this conversation as resolved.
Outdated
constructor(tree, options) {
super([tree], options);

this.options = options;
}

build() {
// TODO: do we need to pass through all files, or only template files?
let files = walkSync(this.inputPaths[0], { directories: false });

let filesToCopy = [];
files.forEach(filePath => {
let filePathParts = path.parse(filePath);
let inputPath = path.join(this.inputPaths[0], filePath);

// TODO: why are these different?
// Apps: my-app/components/foo.hbs, my-app/templates/components/foo.hbs
// Addons: components/foo.js, templates/components/foo.hbs

// TODO: make this more robust
let isInsideComponentsFolder =
(filePath.includes('/components/') || filePath.startsWith('components/')) &&
!filePath.includes('/templates/components/') &&
!filePath.startsWith('templates/components');

// copy forward non-hbs files
// TODO: don't copy .js files that will ultimately be overridden
if (!isInsideComponentsFolder || filePathParts.ext !== '.hbs') {
filesToCopy.push(filePath);
return;
}

// TODO: deal with alternate extensions (e.g. ts)
let possibleJSPath = path.join(filePathParts.dir, filePathParts.name + '.js');
let hasJSFile = fs.existsSync(path.join(this.inputPaths[0], possibleJSPath));

if (filePathParts.name === 'template') {
// TODO: maybe warn?
return;
}

let templateContents = fs.readFileSync(inputPath, { encoding: 'utf8' });
let jsContents = null;

// TODO: deal with hygiene
if (hasJSFile) {
// add the template, call setComponentTemplate

jsContents = fs.readFileSync(path.join(this.inputPaths[0], possibleJSPath), { encoding: 'utf8' });

if (jsContents.includes('export default')) {
jsContents = jsContents.replace('export default', 'const CLASS =');
} else {
let message = `${filePath}\` does not contain a \`default export\`. Did you forget to export the component class?`;
jsContents = `${jsContents}\nthrow new Error(${JSON.stringify(message)})`;
}

jsContents = `${jsContents}
const setComponentTemplate = Ember._setComponentTemplate;
const TEMPLATE = ${this.options.precompile(templateContents)};
export default setComponentTemplate(TEMPLATE, CLASS);`;
} else {
// create JS file, use null component pattern
jsContents = `const templateOnlyComponent = Ember._templateOnlyComponent;
const setComponentTemplate = Ember._setComponentTemplate;
const TEMPLATE = ${this.options.precompile(templateContents)};
const CLASS = templateOnlyComponent();
export default setComponentTemplate(TEMPLATE, CLASS);`;
}


let outputPath = path.join(this.outputPath, possibleJSPath);

// TODO: check for compat with Node 8 (recursive may only be present in 10+)
// TODO: don't speculatively mkdirSync (likely do in a try/catch with ENOENT)
fs.mkdirSync(path.dirname(outputPath), { recursive: true });

fs.writeFileSync(outputPath, jsContents, { encoding: 'utf8' });
});

filesToCopy.forEach(filePath => {
let inputPath = path.join(this.inputPaths[0], filePath);
let outputPath = path.join(this.outputPath, filePath);

// avoid copying file over top of a previously written one
if (fs.existsSync(outputPath)) {
return;
}

// TODO: check for compat with Node 8 (recursive may only be present in 10+)
// TODO: don't speculatively mkdirSync (likely do in a try/catch with ENOENT)
fs.mkdirSync(path.dirname(outputPath), { recursive: true });
fs.copyFileSync(inputPath, outputPath);
})
}
}

module.exports = {
name: require('./package').name,
Expand Down Expand Up @@ -37,21 +138,25 @@ module.exports = {
// ensure that broccoli-ember-hbs-template-compiler is not processing hbs files
registry.remove('template', 'broccoli-ember-hbs-template-compiler');

let precompile = string => {
let htmlbarsOptions = this.htmlbarsOptions();
let templateCompiler = htmlbarsOptions.templateCompiler;
return utils.template(templateCompiler, string);
}

registry.add('template', {
name: 'ember-cli-htmlbars',
ext: 'hbs',
_addon: this,
toTree(tree) {
let htmlbarsOptions = this._addon.htmlbarsOptions();
let TemplateCompiler = require('./index');
return new TemplateCompiler(tree, htmlbarsOptions);
let unifiedColocatedTemplates = new ColocatedTemplateProcessor(tree, { precompile });

return new TemplateCompiler(unifiedColocatedTemplates, htmlbarsOptions);
},

precompile(string) {
let htmlbarsOptions = this._addon.htmlbarsOptions();
let templateCompiler = htmlbarsOptions.templateCompiler;
return utils.template(templateCompiler, string);
}
precompile,
});

if (type === 'parent') {
Expand Down
6 changes: 4 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,16 +35,18 @@
},
"dependencies": {
"broccoli-persistent-filter": "^2.3.1",
"broccoli-plugin": "^2.0.0",
"hash-for-dep": "^1.5.1",
"json-stable-stringify": "^1.0.1",
"strip-bom": "^3.0.0"
"strip-bom": "^3.0.0",
"walk-sync": "^1.1.3"
},
"devDependencies": {
"@ember/optional-features": "^0.7.0",
"broccoli-test-helper": "^2.0.0",
"chai": "^4.2.0",
"co": "^4.6.0",
"ember-cli": "~3.9.0",
"ember-cli": "github:ember-cli/ember-cli",
Comment thread
rwjblue marked this conversation as resolved.
Outdated
"ember-cli-app-version": "^3.2.0",
"ember-cli-babel": "^7.8.0",
"ember-cli-dependency-checker": "^3.2.0",
Expand Down
1 change: 1 addition & 0 deletions tests/dummy/app/components/bar.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Hello from bar!
3 changes: 3 additions & 0 deletions tests/dummy/app/components/bar.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export default Component.extend({
attributeBindings: ['lolol'],
});
1 change: 1 addition & 0 deletions tests/dummy/app/components/foo.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Stuff!!
Empty file.
Loading