diff --git a/README.md b/README.md index f8e7416..f4b46c0 100644 --- a/README.md +++ b/README.md @@ -59,6 +59,24 @@ module.exports = { } ``` +## Custom export names + +In some cases, you may want to customize the formatting of the generated export names. +In this case, you can pass in a custom `formatExports` function to the plugin constructor: + +```js + plugins: [ + new DotIndexPlugin({ + path: path.join(__dirname, '../src'), + formatExports: (filename, rootPath) => filename.toUpperCase() + }) + ], + + // ... will result in ... + + export { default as MYCOMPONENT } from './MyComponent' +``` + ## Limitations This plugin hijacks the default "watch" functionality in order to watch for newly added files. diff --git a/src/dot-index-plugin.js b/src/dot-index-plugin.js index b2b0366..de142f9 100644 --- a/src/dot-index-plugin.js +++ b/src/dot-index-plugin.js @@ -8,13 +8,13 @@ function DotIndexPlugin (options={}) { } DotIndexPlugin.prototype.apply = function (compiler) { - const rootPath = this.options.path + const { path: rootPath, ...options } = this.options if (!rootPath) throw new Error('DotIndexPlugin requires "path" option') function recompile () { return compiler.run(() => {}) } compiler.hooks.watchRun.tapAsync('DotIndexPlugin', (compilation, callback) => { - createDotIndexFiles(rootPath) + createDotIndexFiles(rootPath, options) // Only initialize once if (this.initialized) return callback() createMonitor(rootPath, monitor => { @@ -26,7 +26,7 @@ DotIndexPlugin.prototype.apply = function (compiler) { }) }) compiler.hooks.run.tapAsync('DotIndexPlugin', (compilation, callback) => { - createDotIndexFiles(rootPath) + createDotIndexFiles(rootPath, options) callback() }) } diff --git a/src/generate-dot-index-files.js b/src/generate-dot-index-files.js index eb52d9d..2db9a70 100644 --- a/src/generate-dot-index-files.js +++ b/src/generate-dot-index-files.js @@ -2,11 +2,9 @@ const createDotIndexFiles = require('./utils/create-dot-index-files') -function main (args=process.argv.slice(2)) { - const rootPath = args[0] +function main ([ rootPath, options ]=process.argv.slice(2)) { if (!rootPath) throw new Error('Must provide "path" argument') - // console.log(rootPath) - return createDotIndexFiles(rootPath) + return createDotIndexFiles(rootPath, options) } module.exports = main diff --git a/src/utils/create-dot-index-files.js b/src/utils/create-dot-index-files.js index b258f2b..997baea 100644 --- a/src/utils/create-dot-index-files.js +++ b/src/utils/create-dot-index-files.js @@ -3,16 +3,14 @@ const path = require('path') const createIndexFileContent = require('./create-index-file-content') const getFilesAndDirectories = require('./get-files-and-directories') -function createDotIndexFiles (rootPath) { +function createDotIndexFiles (rootPath, options={}) { const to = relPath => path.join(rootPath, relPath) const { files, directories } = getFilesAndDirectories(rootPath) - // console.log(files, directories) - // return if (files.includes('index.js')) { if (files.includes('.index.js')) fs.removeSync(to('.index.js')) } else { const existingContent = attemptRead(to('.index.js')) - const newContent = createIndexFileContent([ ...files, ...directories ]) + const newContent = createIndexFileContent([ ...files, ...directories ], rootPath, options) if (newContent !== existingContent) fs.writeFileSync(to('.index.js'), newContent) } directories.forEach(dir => createDotIndexFiles(to(dir))) diff --git a/src/utils/create-index-file-content.js b/src/utils/create-index-file-content.js index 401f240..7a150df 100644 --- a/src/utils/create-index-file-content.js +++ b/src/utils/create-index-file-content.js @@ -8,16 +8,16 @@ function isKebabCase (fileName) { return fileName.includes('-') } -function toExportName (fileName) { - const stripped = stripExtension(fileName) - return isKebabCase(stripped) ? camelcase(stripped) : stripped +function defaultFormatExports (fileName, rootPath) { + return isKebabCase(fileName) ? camelcase(fileName) : fileName } -function createIndexFileContent (files=[]) { +function createIndexFileContent (files=[], rootPath, { formatExports=defaultFormatExports }={}) { let content = `// This index file was auto-generated by dot-index-webpack-plugin.\n// To overwrite it, simply add an index.js file of your own.\n\n` files.forEach(file => { if (file === '.index.js') return - content += `export { default as ${ toExportName(file) } } from './${ stripExtension(file) }'\n` + const strippedFileName = stripExtension(file) + content += `export { default as ${ formatExports(strippedFileName, rootPath) } } from './${ strippedFileName }'\n` }) return content } diff --git a/test/dot-index-plugin/__snapshots__/dot-index-plugin.test.js.snap b/test/dot-index-plugin/__snapshots__/dot-index-plugin.test.js.snap index 6dc4bc9..3189258 100644 --- a/test/dot-index-plugin/__snapshots__/dot-index-plugin.test.js.snap +++ b/test/dot-index-plugin/__snapshots__/dot-index-plugin.test.js.snap @@ -1,5 +1,14 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`Accepts formatExports argument 1`] = ` +"// This index file was auto-generated by dot-index-webpack-plugin. +// To overwrite it, simply add an index.js file of your own. + +export { default as MYCOMPONENT } from './MyComponent'; +export { default as MYKEBABCASEDFUNCTION } from './my-kebab-cased-function'; +export { default as MYFUNCTION } from './myFunction';" +`; + exports[`Generates dot index files 1`] = ` "// This index file was auto-generated by dot-index-webpack-plugin. // To overwrite it, simply add an index.js file of your own. diff --git a/test/dot-index-plugin/dot-index-plugin.test.js b/test/dot-index-plugin/dot-index-plugin.test.js index 1de937b..6c6c40b 100644 --- a/test/dot-index-plugin/dot-index-plugin.test.js +++ b/test/dot-index-plugin/dot-index-plugin.test.js @@ -40,7 +40,42 @@ test('Generates dot index files', end => { }) -afterAll(() => { +test('Accepts formatExports argument', end => { + const toUpperCase = filename => filename.replace(/-/g, '').toUpperCase() + const config = { + entry: to('./test-input'), + output: { + path: to('./test-output'), + filename: '[name].js' + }, + module: { + rules: [ + { + test: /\.js$/, + use: 'babel-loader', + }, + ], + }, + resolve: { + mainFiles: ['index', '.index'], + }, + plugins: [ + new DotIndexPlugin({ path: to('./test-input'), formatExports: toUpperCase }) + ] + } + + webpack(config, (err, stats) => { + expect(err).toEqual(null) + const modules = stats.toJson().modules + expect(modules.length).toEqual(4) + const indexFileContent = modules.pop().source + expect(indexFileContent).toMatchSnapshot() + end() + }) + +}) + +afterEach(() => { fs.removeSync(to('./test-input/.index.js')) fs.removeSync(to('./test-output')) }) \ No newline at end of file diff --git a/test/generate-dot-index-files/__snapshots__/generate-dot-index-files.test.js.snap b/test/generate-dot-index-files/__snapshots__/generate-dot-index-files.test.js.snap index 2045811..5ca9785 100644 --- a/test/generate-dot-index-files/__snapshots__/generate-dot-index-files.test.js.snap +++ b/test/generate-dot-index-files/__snapshots__/generate-dot-index-files.test.js.snap @@ -1,5 +1,15 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`Accepts formatExports argument 1`] = ` +"// This index file was auto-generated by dot-index-webpack-plugin. +// To overwrite it, simply add an index.js file of your own. + +export { default as MYCOMPONENT } from './MyComponent' +export { default as MYKEBABCASEDFUNCTION } from './my-kebab-cased-function' +export { default as MYFUNCTION } from './myFunction' +" +`; + exports[`Generates dot index file correctly 1`] = ` "// This index file was auto-generated by dot-index-webpack-plugin. // To overwrite it, simply add an index.js file of your own. diff --git a/test/generate-dot-index-files/generate-dot-index-files.test.js b/test/generate-dot-index-files/generate-dot-index-files.test.js index b6513e1..fe9f883 100644 --- a/test/generate-dot-index-files/generate-dot-index-files.test.js +++ b/test/generate-dot-index-files/generate-dot-index-files.test.js @@ -15,6 +15,14 @@ test('Generates dot index file correctly', () => { expect(indexFileContent).toMatchSnapshot() }) -afterAll(() => { +test('Accepts formatExports argument', () => { + const toUpperCase = filename => filename.replace(/-/g, '').toUpperCase() + generateDotIndexFiles([ to('./test-input'), { formatExports: toUpperCase } ]) + expect(fs.existsSync(to('./test-input/.index.js'))).toEqual(true) + const indexFileContent = fs.readFileSync(to('./test-input/.index.js')).toString() + expect(indexFileContent).toMatchSnapshot() +}) + +afterEach(() => { fs.removeSync(to('./test-input/.index.js')) })