Skip to content

Commit 4bfb820

Browse files
authored
Merge pull request #124 from typed-ember/mirage
Support ember-cli-mirage out of the box
2 parents a2d581a + ff6f642 commit 4bfb820

File tree

4 files changed

+142
-2
lines changed

4 files changed

+142
-2
lines changed

README.md

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ Use TypeScript in your Ember 2.x and 3.x apps!
2222
* [Fixing the Ember Data `error TS2344` problem](#fixing-the-ember-data-error-ts2344-problem)
2323
* [Type definitions outside `node_modules/@types`](#type-definitions-outside-node_modulestypes)
2424
* [ember-browserify](#ember-browserify)
25+
* [ember-cli-mirage](#ember-cli-mirage)
2526
* ["TypeScript is complaining about multiple copies of the same types"](#typescript-is-complaining-about-multiple-copies-of-the-same-types)
2627
* [Just tell me how to fix it](#just-tell-me-how-to-fix-it)
2728
* [Why is this happening?](#why-is-this-happening)
@@ -410,7 +411,7 @@ If you're using [ember-browserify], you're used to writing imports like this:
410411
[ember-browserify]: https://github.com/ef4/ember-browserify
411412

412413
```js
413-
import 'npm:my-module' from 'my-module';
414+
import MyModule from 'npm:my-module';
414415
```
415416

416417
If the `my-module` has types, you will not be able to resolve them this way by default. You can add a simple tweak to your `tsconfig.json` to resolve the types correctly, hwowever:
@@ -426,6 +427,47 @@ If the `my-module` has types, you will not be able to resolve them this way by d
426427
}
427428
```
428429

430+
### ember-cli-mirage
431+
432+
Mirage adds files from a nonstandard location to your application tree, so you'll need to tell the TypeScript compiler about how that layout works.
433+
434+
For an app, this should look roughly like:
435+
436+
```js
437+
{
438+
"compilerOptions": {
439+
"paths": {
440+
// ...
441+
"my-app-name/mirage/*": "mirage/*",
442+
}
443+
},
444+
"include": [
445+
"app",
446+
"tests",
447+
"mirage"
448+
]
449+
}
450+
```
451+
452+
And for an addon:
453+
454+
```js
455+
{
456+
"compilerOptions": {
457+
"paths": {
458+
// ...
459+
"dummy/mirage/*": "tests/dummy/mirage/*",
460+
}
461+
},
462+
"include": [
463+
"addon",
464+
"tests"
465+
]
466+
}
467+
```
468+
469+
Note that if Mirage was present when you installed ember-cli-typescript (or if you run `ember g ember-cli-typescript`), this configuration should be automatically set up for you.
470+
429471
### "TypeScript is complaining about multiple copies of the same types!"
430472

431473
You may sometimes see TypeScript errors indicating that you have duplicate type definitions for Ember, Ember Data, etc. This is usually the result of an annoying quirk of the way both npm and yarn resolve your dependencies in their lockfiles.

blueprints/ember-cli-typescript/index.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,15 @@ module.exports = {
2929

3030
locals() {
3131
let inRepoAddons = (this.project.pkg['ember-addon'] || {}).paths || [];
32+
let hasMirage = 'ember-cli-mirage' in (this.project.pkg.devDependencies || {});
3233
let isAddon = this.project.isEmberCLIAddon();
3334
let includes = [isAddon ? 'addon' : 'app', 'tests'].concat(inRepoAddons);
3435

36+
// Mirage is already covered for addons because it's under `tests/`
37+
if (hasMirage && !isAddon) {
38+
includes.push('mirage');
39+
}
40+
3541
return {
3642
includes: JSON.stringify(includes, null, 2).replace(/\n/g, '\n '),
3743
pathsFor: dasherizedName => {
@@ -40,6 +46,10 @@ module.exports = {
4046
[`${appName}/tests/*`]: ['tests/*'],
4147
};
4248

49+
if (hasMirage) {
50+
paths[`${appName}/mirage/*`] = [`${isAddon ? 'tests/dummy/' : ''}mirage/*`];
51+
}
52+
4353
if (isAddon) {
4454
paths[`${appName}/*`] = ['tests/dummy/app/*'];
4555
} else {

lib/incremental-typescript-compiler.js

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,12 @@ module.exports = class IncrementalTypescriptCompiler {
5555
[`${this._relativeAppRoot()}/app`]: 'app',
5656
});
5757

58-
let tree = new MergeTrees(addonAppTrees.concat([triggerTree, appTree]), { overwrite: true });
58+
let mirage = this._mirageDirectory();
59+
let mirageTree = mirage && new TypescriptOutput(this, {
60+
[mirage]: 'app/mirage',
61+
});
62+
63+
let tree = new MergeTrees(addonAppTrees.concat([triggerTree, appTree, mirageTree].filter(Boolean)), { overwrite: true });
5964
return new Funnel(tree, { srcDir: 'app' });
6065
}
6166

@@ -159,6 +164,31 @@ module.exports = class IncrementalTypescriptCompiler {
159164
this._buildDeferred.resolve();
160165
}
161166

167+
_mirageDirectory() {
168+
let mirage = this.project.addons.find(addon => addon.name === 'ember-cli-mirage');
169+
if (mirage) {
170+
// Be a little defensive, since we're using an internal Mirage API
171+
if (
172+
typeof mirage._shouldIncludeFiles !== 'function' ||
173+
typeof mirage.mirageDirectory !== 'string'
174+
) {
175+
this.ui.writeWarnLine(
176+
`Couldn't determine whether to include Mirage files. This is likely a bug in ember-cli-typescript; ` +
177+
`please file an issue at https://github.com/typed-ember/ember-cli-typescript`
178+
);
179+
return;
180+
}
181+
182+
if (mirage._shouldIncludeFiles()) {
183+
let source = mirage.mirageDirectory;
184+
if (source.indexOf(this.project.root) === 0) {
185+
source = source.substring(this.project.root.length + 1);
186+
}
187+
return source;
188+
}
189+
}
190+
}
191+
162192
_touchRebuildTrigger() {
163193
debugAutoresolve('touching rebuild trigger.');
164194
fs.writeFileSync(`${this._triggerDir}/tsc-delayed-rebuild`, '', 'utf-8');

node-tests/blueprints/ember-cli-typescript-test.js

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,4 +118,62 @@ describe('Acceptance: ember-cli-typescript generator', function() {
118118
expect(projectTypes).to.include(ects.APP_DECLARATIONS);
119119
});
120120
});
121+
122+
it('app with Mirage', function() {
123+
const args = ['ember-cli-typescript'];
124+
125+
return helpers
126+
.emberNew()
127+
.then(() => {
128+
const packagePath = path.resolve(process.cwd(), 'package.json');
129+
const contents = JSON.parse(fs.readFileSync(packagePath, { encoding: 'utf8' }));
130+
contents.devDependencies['ember-cli-mirage'] = '*';
131+
fs.writeFileSync(packagePath, JSON.stringify(contents, null, 2));
132+
})
133+
.then(() => helpers.emberGenerate(args))
134+
.then(() => {
135+
const tsconfig = file('tsconfig.json');
136+
expect(tsconfig).to.exist;
137+
138+
const json = JSON.parse(tsconfig.content);
139+
expect(json.compilerOptions.paths).to.deep.equal({
140+
'my-app/tests/*': ['tests/*'],
141+
'my-app/mirage/*': ['mirage/*'],
142+
'my-app/*': ['app/*'],
143+
'*': ['types/*'],
144+
});
145+
146+
expect(json.include).to.deep.equal(['app', 'tests', 'mirage']);
147+
});
148+
});
149+
150+
it('addon with Mirage', function() {
151+
const args = ['ember-cli-typescript'];
152+
153+
return helpers
154+
.emberNew({ target: 'addon' })
155+
.then(() => {
156+
const packagePath = path.resolve(process.cwd(), 'package.json');
157+
const contents = JSON.parse(fs.readFileSync(packagePath, { encoding: 'utf8' }));
158+
contents.devDependencies['ember-cli-mirage'] = '*';
159+
fs.writeFileSync(packagePath, JSON.stringify(contents, null, 2));
160+
})
161+
.then(() => helpers.emberGenerate(args))
162+
.then(() => {
163+
const tsconfig = file('tsconfig.json');
164+
expect(tsconfig).to.exist;
165+
166+
const json = JSON.parse(tsconfig.content);
167+
expect(json.compilerOptions.paths).to.deep.equal({
168+
'dummy/tests/*': ['tests/*'],
169+
'dummy/mirage/*': ['tests/dummy/mirage/*'],
170+
'dummy/*': ['tests/dummy/app/*'],
171+
'my-addon': ['addon'],
172+
'my-addon/*': ['addon/*'],
173+
'*': ['types/*'],
174+
});
175+
176+
expect(json.include).to.deep.equal(['addon', 'tests']);
177+
});
178+
});
121179
});

0 commit comments

Comments
 (0)