Skip to content

Commit 33c3f74

Browse files
author
Robert Jackson
authored
Enable colocated component classes to be TypeScript (#333)
Enable colocated component classes to be TypeScript
2 parents c6f42ea + 7a46bea commit 33c3f74

2 files changed

Lines changed: 64 additions & 8 deletions

File tree

lib/colocated-broccoli-plugin.js

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -68,15 +68,25 @@ module.exports = class ColocatedTemplateProcessor extends Plugin {
6868
return;
6969
}
7070

71-
// TODO: deal with alternate extensions (e.g. ts)
72-
let possibleJSPath = path.join(filePathParts.dir, filePathParts.name + '.js');
73-
let hasJSFile = fs.existsSync(path.join(this.inputPaths[0], possibleJSPath));
74-
7571
if (filePathParts.name === 'template') {
7672
filesToCopy.push(filePath);
7773
return;
7874
}
7975

76+
let hasBackingClass = false;
77+
let backingClassPath = path.join(filePathParts.dir, filePathParts.name);
78+
79+
if (fs.existsSync(path.join(this.inputPaths[0], backingClassPath + '.js'))) {
80+
backingClassPath += '.js';
81+
hasBackingClass = true;
82+
} else if (fs.existsSync(path.join(this.inputPaths[0], backingClassPath + '.ts'))) {
83+
backingClassPath += '.ts';
84+
hasBackingClass = true;
85+
} else {
86+
backingClassPath += '.js';
87+
hasBackingClass = false;
88+
}
89+
8090
let templateContents = fs.readFileSync(inputPath, { encoding: 'utf8' });
8191
let jsContents = null;
8292

@@ -92,12 +102,14 @@ module.exports = class ColocatedTemplateProcessor extends Plugin {
92102
)})`;
93103
let prefix = `import { hbs } from 'ember-cli-htmlbars';\nconst __COLOCATED_TEMPLATE__ = ${hbsInvocation};\n`;
94104

95-
logger.debug(`processing colocated template: ${filePath} (template-only: ${hasJSFile})`);
105+
logger.debug(
106+
`processing colocated template: ${filePath} (template-only: ${hasBackingClass})`
107+
);
96108

97-
if (hasJSFile) {
109+
if (hasBackingClass) {
98110
// add the template, call setComponentTemplate
99111

100-
jsContents = fs.readFileSync(path.join(this.inputPaths[0], possibleJSPath), {
112+
jsContents = fs.readFileSync(path.join(this.inputPaths[0], backingClassPath), {
101113
encoding: 'utf8',
102114
});
103115

@@ -114,7 +126,7 @@ module.exports = class ColocatedTemplateProcessor extends Plugin {
114126

115127
jsContents = prefix + jsContents;
116128

117-
let outputPath = path.join(this.outputPath, possibleJSPath);
129+
let outputPath = path.join(this.outputPath, backingClassPath);
118130

119131
// TODO: don't speculatively mkdirSync (likely do in a try/catch with ENOENT)
120132
mkdirp.sync(path.dirname(outputPath));

node-tests/colocated-plugin-test.js

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,50 @@ describe('ColocatedTemplateCompiler', function() {
105105
});
106106
});
107107

108+
it('works for typescript component class with template', async function() {
109+
input.write({
110+
'app-name-here': {
111+
components: {
112+
'foo.hbs': `{{yield}}`,
113+
'foo.ts': stripIndent`
114+
import Component from '@glimmer/component';
115+
116+
export default class FooComponent extends Component {}
117+
`,
118+
},
119+
templates: {
120+
'application.hbs': `{{outlet}}`,
121+
},
122+
},
123+
});
124+
125+
let tree = new ColocatedTemplateCompiler(input.path(), {
126+
precompile(template) {
127+
return JSON.stringify({ template });
128+
},
129+
});
130+
131+
output = createBuilder(tree);
132+
await output.build();
133+
134+
assert.deepStrictEqual(output.read(), {
135+
'app-name-here': {
136+
components: {
137+
'foo.ts': stripIndent`
138+
import { hbs } from 'ember-cli-htmlbars';
139+
const __COLOCATED_TEMPLATE__ = hbs("{{yield}}", {"contents":"{{yield}}","moduleName":"app-name-here/components/foo.hbs","parseOptions":{"srcName":"app-name-here/components/foo.hbs"}});
140+
import Component from '@glimmer/component';
141+
142+
export default class FooComponent extends Component {}
143+
`,
144+
},
145+
templates: {
146+
'application.hbs': '{{outlet}}',
147+
},
148+
},
149+
});
150+
});
151+
108152
it('works for scoped addon using template only component', async function() {
109153
input.write({
110154
'@scope-name': {

0 commit comments

Comments
 (0)