Skip to content

Commit f734dda

Browse files
TrySoundgregberge
authored andcommitted
feat: allow to provide custom index.js template (#378)
New index.js generator does not cover my cases. 1. need to add `// @flow` on top of the file 2. need to use named export Both can be easily solved with indexTemplate option. ``` function indexTemplate(files) { const exportEntries = files.map(file => { const basename = path.basename(file, path.extname(file)) return `export { ${basename} } from './${basename}'` }) return '// @flow\n' + exportEntries.join('\n') } ```
1 parent 61a7ddb commit f734dda

File tree

7 files changed

+99
-6
lines changed

7 files changed

+99
-6
lines changed
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
const path = require('path')
2+
3+
function indexTemplate(files) {
4+
const exportEntries = files.map(file => {
5+
const basename = path.basename(file, path.extname(file))
6+
return `export { ${basename} } from './${basename}'`
7+
})
8+
return exportEntries.join('\n')
9+
}
10+
11+
module.exports = indexTemplate
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
const indexTemplate = require('./custom-index-template.js')
2+
3+
function template(
4+
{ template },
5+
opts,
6+
{ imports, componentName, props, jsx, exports },
7+
) {
8+
return template.ast`${imports}
9+
export function ${componentName}(${props}) {
10+
return ${jsx};
11+
}
12+
`
13+
}
14+
15+
module.exports = {
16+
template,
17+
indexTemplate,
18+
}

packages/cli/src/__snapshots__/index.test.js.snap

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ export default SvgFile;
1111
"
1212
`;
1313

14+
exports[`cli should support --index-template in cli 1`] = `"export { File } from './File'"`;
15+
1416
exports[`cli should support --prettier-config as file 1`] = `
1517
"import React from 'react'
1618
@@ -84,6 +86,8 @@ Array [
8486
]
8587
`;
8688

89+
exports[`cli should support custom index.js with directory output 1`] = `"export { File } from './File'"`;
90+
8791
exports[`cli should support different filename cases with directory output 1`] = `
8892
Array [
8993
"CamelCase.js",

packages/cli/src/dirCommand.js

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { promisify } from 'util'
44
import path from 'path'
55
import chalk from 'chalk'
66
import outputFileSync from 'output-file-sync'
7+
import { loadConfig } from '@svgr/core'
78
import { convertFile, stat, transformFilename, CASE, politeWrite } from './util'
89

910
const access = promisify(fs.access)
@@ -34,6 +35,14 @@ export function isCompilable(filename) {
3435
return COMPILABLE_EXTENSIONS.includes(ext)
3536
}
3637

38+
function defaultIndexTemplate(files) {
39+
const exportEntries = files.map(file => {
40+
const basename = path.basename(file, path.extname(file))
41+
return `export { default as ${basename} } from './${basename}'`
42+
})
43+
return exportEntries.join('\n')
44+
}
45+
3746
export default async function dirCommand(
3847
program,
3948
filenames,
@@ -59,11 +68,9 @@ export default async function dirCommand(
5968

6069
async function generateIndex(dest, files) {
6170
const indexFile = path.join(dest, `index.${ext}`)
62-
const exportEntries = files.map(file => {
63-
const basename = path.basename(file, path.extname(file))
64-
return `export { default as ${basename} } from './${basename}'`
65-
})
66-
fs.writeFileSync(indexFile, exportEntries.join('\n'))
71+
const config = loadConfig.sync(options, { filePath: indexFile })
72+
const indexTemplate = config.indexTemplate || defaultIndexTemplate
73+
fs.writeFileSync(indexFile, indexTemplate(files))
6774
}
6875

6976
async function handle(filename, root) {

packages/cli/src/index.js

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,10 @@ program
7474
parseObjectList,
7575
)
7676
.option('--template <file>', 'specify a custom template to use')
77+
.option(
78+
'--index-template <file>',
79+
'specify a custom index.js template to use',
80+
)
7781
.option('--title-prop', 'create a title element linked with props')
7882
.option(
7983
'--prettier-config <fileOrJson>',
@@ -146,7 +150,8 @@ async function run() {
146150

147151
if (config.template) {
148152
try {
149-
const template = require(path.join(process.cwd(), program.template)) // eslint-disable-line global-require, import/no-dynamic-require
153+
// eslint-disable-next-line global-require, import/no-dynamic-require
154+
const template = require(path.join(process.cwd(), program.template))
150155
if (template.default) config.template = template.default
151156
else config.template = template
152157

@@ -159,6 +164,27 @@ async function run() {
159164
}
160165
}
161166

167+
if (config.indexTemplate) {
168+
try {
169+
// eslint-disable-next-line global-require, import/no-dynamic-require
170+
const indexTemplate = require(path.join(
171+
process.cwd(),
172+
program.indexTemplate,
173+
))
174+
if (indexTemplate.default) config.indexTemplate = indexTemplate.default
175+
else config.indexTemplate = indexTemplate
176+
177+
if (typeof config.indexTemplate !== 'function')
178+
throw new Error('indexTemplate must be a function')
179+
} catch (error) {
180+
console.error(
181+
`Error when loading indexTemplate: ${program.indexTemplate}\n`,
182+
)
183+
console.error(error.stack)
184+
process.exit(2)
185+
}
186+
}
187+
162188
const command = program.outDir ? dirCommand : fileCommand
163189
await command(program, filenames, config)
164190
}

packages/cli/src/index.test.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,4 +166,22 @@ describe('cli', () => {
166166
)
167167
expect(result).toMatchSnapshot()
168168
}, 10000)
169+
170+
it('should support custom index.js with directory output', async () => {
171+
const inDir = '__fixtures__/simple'
172+
const outDir = `__fixtures_build__/custom-index`
173+
await del(outDir)
174+
await cli(`${inDir} --out-dir=${outDir} --config-file=__fixtures__/custom-index.config.js`)
175+
const content = fs.readFileSync(path.join(outDir, 'index.js'), 'utf-8')
176+
expect(content).toMatchSnapshot()
177+
}, 10000)
178+
179+
it('should support --index-template in cli', async () => {
180+
const inDir = '__fixtures__/simple'
181+
const outDir = `__fixtures_build__/custom-index-arg`
182+
await del(outDir)
183+
await cli(`${inDir} --out-dir=${outDir} --index-template=__fixtures__/custom-index-template.js`)
184+
const content = fs.readFileSync(path.join(outDir, 'index.js'), 'utf-8')
185+
expect(content).toMatchSnapshot()
186+
}, 10000)
169187
})

website/src/pages/docs/options.mdx

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,15 @@ Output files into a directory.
166166
| ----------- | --------------------- | --------------------- |
167167
| `undefined` | `--out-dir <dirname>` | Only available in CLI |
168168

169+
## index.js template
170+
171+
Specify a template function (API) to change default index.js output (when --out-dir is used).
172+
173+
| Default | CLI Override | API Override |
174+
| ------------------ | ------------------ | -------------------------- |
175+
| [`basic template`](https://github.com/gregberge/svgr/blob/master/packages/cli/src/dirCommand.js) | `--index-template` | indexTemplate: files => '' |
176+
177+
169178
## Keep existing
170179

171180
When used with `--out-dir`, it does not override already existing files.

0 commit comments

Comments
 (0)