Skip to content

Commit 42e6a20

Browse files
committed
Support ember-cli-mirage out of the box
1 parent a2d581a commit 42e6a20

File tree

4 files changed

+142
-4
lines changed

4 files changed

+142
-4
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 & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,10 +50,13 @@ module.exports = class IncrementalTypescriptCompiler {
5050
});
5151

5252
let triggerTree = new Funnel(this._triggerDir, { destDir: 'app' });
53-
54-
let appTree = new TypescriptOutput(this, {
53+
let sourceDirectories = {
5554
[`${this._relativeAppRoot()}/app`]: 'app',
56-
});
55+
};
56+
57+
this._maybeIncludeMirage(sourceDirectories);
58+
59+
let appTree = new TypescriptOutput(this, sourceDirectories);
5760

5861
let tree = new MergeTrees(addonAppTrees.concat([triggerTree, appTree]), { overwrite: true });
5962
return new Funnel(tree, { srcDir: 'app' });
@@ -159,6 +162,31 @@ module.exports = class IncrementalTypescriptCompiler {
159162
this._buildDeferred.resolve();
160163
}
161164

165+
_maybeIncludeMirage(sourceDirectories) {
166+
let mirage = this.project.addons.find(addon => addon.name === 'ember-cli-mirage');
167+
if (mirage) {
168+
// Be a little defensive, since we're using an internal Mirage API
169+
if (
170+
typeof mirage._shouldIncludeFiles !== 'function' ||
171+
typeof mirage.mirageDirectory !== 'string'
172+
) {
173+
this.ui.writeWarnLine(
174+
`Couldn't determine whether to include Mirage files. This is likely a bug in ember-cli-typescript; ` +
175+
`please file an issue at https://github.com/typed-ember/ember-cli-typescript`
176+
);
177+
return;
178+
}
179+
180+
if (mirage._shouldIncludeFiles()) {
181+
let source = mirage.mirageDirectory;
182+
if (source.indexOf(this.project.root) === 0) {
183+
source = source.substring(this.project.root.length + 1);
184+
}
185+
sourceDirectories[source] = 'app/mirage';
186+
}
187+
}
188+
}
189+
162190
_touchRebuildTrigger() {
163191
debugAutoresolve('touching rebuild trigger.');
164192
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)