-
Notifications
You must be signed in to change notification settings - Fork 142
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #2200 from embroider-build/si-dts-plugin
Add rollup declarations plugin
- Loading branch information
Showing
6 changed files
with
272 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
module.exports = { | ||
testEnvironment: 'node', | ||
testMatch: [ | ||
'<rootDir>/tests/**/*.test.js', | ||
], | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
import execa from 'execa'; | ||
import walkSync from 'walk-sync'; | ||
import { readFile, writeFile } from 'fs/promises'; | ||
|
||
export default function rollupDeclarationsPlugin(declarationsDir: string) { | ||
let glintPromise: Promise<void>; | ||
|
||
return { | ||
name: 'glint-dts', | ||
buildStart: () => { | ||
const runGlint = async () => { | ||
await execa('glint', ['--declaration'], { | ||
stdio: 'inherit', | ||
preferLocal: true, | ||
}); | ||
|
||
await fixDeclarationsInMatchingFiles(declarationsDir); | ||
}; | ||
|
||
// We just kick off glint here early in the rollup process, without making rollup wait for this to finish, by not returning the promise | ||
// The output of this is not relevant to further stages of the rollup build, this is just happening in parallel to other rollup compilation | ||
glintPromise = runGlint(); | ||
}, | ||
|
||
// Make rollup wait for glint to have finished before calling the build job done | ||
writeBundle: () => glintPromise, | ||
}; | ||
} | ||
|
||
async function fixDeclarationsInMatchingFiles(dir: string) { | ||
const dtsFiles = walkSync(dir, { | ||
globs: ['**/*.d.ts'], | ||
directories: false, | ||
includeBasePath: true, | ||
}); | ||
|
||
return Promise.all( | ||
dtsFiles.map(async (file) => { | ||
const content = await readFile(file, { encoding: 'utf8' }); | ||
|
||
await writeFile(file, fixDeclarations(content)); | ||
}) | ||
); | ||
} | ||
|
||
// Strip any .gts extension from imports in d.ts files, as these won't resolve. See https://github.com/typed-ember/glint/issues/628 | ||
// Once Glint v2 is available, this shouldn't be needed anymore. | ||
function fixDeclarations(content: string) { | ||
return content.replace(/from\s+['"]([^'"]+)\.gts['"]/g, `from '$1'`); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
'use strict'; | ||
|
||
import rollupDeclarationsPlugin from '../src/rollup-declarations'; | ||
import { Project } from 'scenario-tester'; | ||
import { rollup } from 'rollup'; | ||
import { readFile } from 'fs-extra'; | ||
import { join } from 'path'; | ||
|
||
const projectBoilerplate = { | ||
'tsconfig.json': JSON.stringify({ | ||
include: ['src/**/*'], | ||
compilerOptions: { | ||
declaration: true, | ||
declarationDir: 'declarations', | ||
emitDeclarationOnly: true, | ||
rootDir: './src', | ||
allowImportingTsExtensions: true, | ||
}, | ||
glint: { | ||
environment: ['ember-loose', 'ember-template-imports'], | ||
}, | ||
}), | ||
}; | ||
|
||
async function generateProject(src: {}): Promise<Project> { | ||
const project = new Project('my-addon', { | ||
files: { | ||
...projectBoilerplate, | ||
src, | ||
}, | ||
}); | ||
project.linkDevDependency('typescript', { baseDir: __dirname }); | ||
project.linkDevDependency('@glint/core', { baseDir: __dirname }); | ||
project.linkDevDependency('@glint/template', { baseDir: __dirname }); | ||
project.linkDevDependency('@glint/environment-ember-loose', { | ||
baseDir: __dirname, | ||
}); | ||
project.linkDevDependency('@glint/environment-ember-template-imports', { | ||
baseDir: __dirname, | ||
}); | ||
|
||
await project.write(); | ||
|
||
return project; | ||
} | ||
|
||
async function runRollup(dir: string, rollupOptions = {}) { | ||
const currentDir = process.cwd(); | ||
process.chdir(dir); | ||
|
||
try { | ||
const bundle = await rollup({ | ||
input: './src/index.ts', | ||
plugins: [rollupDeclarationsPlugin('declarations')], | ||
...rollupOptions, | ||
}); | ||
|
||
await bundle.write({ format: 'esm', dir: 'dist' }); | ||
} finally { | ||
process.chdir(currentDir); | ||
} | ||
} | ||
|
||
describe('declarations', function () { | ||
let project: Project | null; | ||
|
||
afterEach(() => { | ||
project?.dispose(); | ||
project = null; | ||
}); | ||
|
||
test('it generates dts output', async function () { | ||
project = await generateProject({ | ||
'index.ts': 'export default 123', | ||
}); | ||
|
||
await runRollup(project.baseDir); | ||
|
||
expect( | ||
await readFile(join(project.baseDir, 'declarations/index.d.ts'), { | ||
encoding: 'utf8', | ||
}) | ||
).toContain('export default'); | ||
}); | ||
|
||
test('it has correct imports', async function () { | ||
project = await generateProject({ | ||
'index.ts': ` | ||
import foo from './foo.gts'; | ||
import bar from './bar.gts'; | ||
import baz from './baz.ts'; | ||
export { foo, bar, baz }; | ||
`, | ||
'foo.gts': 'export default 123', | ||
'bar.gts': 'export default 234', | ||
'baz.ts': 'export default 345', | ||
}); | ||
|
||
await runRollup(project.baseDir); | ||
|
||
const output = await readFile( | ||
join(project.baseDir, 'declarations/index.d.ts'), | ||
{ | ||
encoding: 'utf8', | ||
} | ||
); | ||
|
||
expect(output).toContain(`import foo from './foo';`); | ||
expect(output).toContain(`import bar from './bar';`); | ||
expect(output).toContain(`import baz from './baz.ts';`); | ||
}); | ||
}); |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.