vue-sfc-rollup
Advanced tools
Comparing version 1.0.3 to 1.1.0
@@ -13,2 +13,18 @@ # Changelog | ||
## [1.1.0] - 2019-01-31 | ||
### Changed | ||
- Drop 'readline-sync' for 'prompts' - better UX, allow cli to be canceled | ||
- Update template dependencies | ||
- vue 2.5.22 | ||
- vue-template-compiler 2.5.21 | ||
- rollup 1.1.2 | ||
- rollup-plugin-vue 4.6.2 | ||
- \*new* rollup-plugin-commonjs 9.2.0 (due to rollup-plugin-vue) | ||
## [1.0.3] - 2019-01-12 | ||
### Fixed | ||
- export install function in lib mode. singe/lib modes can now be registered via both Vue.use() and Vue.component(). | ||
## [1.0.2] - 2019-01-12 | ||
@@ -15,0 +31,0 @@ |
@@ -6,3 +6,3 @@ { | ||
"license": "ISC", | ||
"version": "1.0.3", | ||
"version": "1.1.0", | ||
"bin": { | ||
@@ -27,3 +27,3 @@ "sfc-rollup-init": "./sfc-init.js" | ||
"ejs": "^2.6.1", | ||
"readline-sync": "^1.4.9" | ||
"prompts": "^2.0.1" | ||
}, | ||
@@ -30,0 +30,0 @@ "devDependencies": { |
@@ -6,5 +6,15 @@ # vue-sfc-rollup | ||
## TL;DR | ||
Install globally | ||
```bash | ||
# Install globally (recommended) | ||
npm install -g vue-sfc-rollup | ||
sfc-rollup-init | ||
``` | ||
**OR** use via npx | ||
```bash | ||
# For immediate, no-install usage | ||
npx vue-sfc-rollup | ||
``` | ||
Then... | ||
```bash | ||
# fill in prompts | ||
@@ -30,4 +40,6 @@ cd path/to/my-component-or-lib | ||
To install [vue-sfc-rollup](https://www.npmjs.com/package/vue-sfc-rollup), simply open a terminal and execute the following: | ||
If you just want to try [vue-sfc-rollup](https://www.npmjs.com/package/vue-sfc-rollup), you can run it directly via `npx vue-sfc-rollup`. | ||
For repeated use, however, you really should install it globally. To do so, simply open a terminal and execute the following: | ||
```bash | ||
@@ -37,7 +49,7 @@ npm install -g vue-sfc-rollup | ||
Now, whenever you want to start a new component, you can just type `sfc-rollup-init` to run the wizard to scaffold a new SFC for you! | ||
Now, whenever you want to start a new component, you can just type `sfc-rollup-init` to run the wizard, and it will scaffold a new SFC for you! | ||
### Using the vue-sfc-rollup wizard | ||
Using the vue-sfc-rollup wizard is simple: | ||
Using the vue-sfc-rollup wizard is simple. With vue-sfc-rollup installed globally, enter the following: | ||
```bash | ||
@@ -47,3 +59,3 @@ sfc-rollup-init | ||
``` | ||
The wizard will prompt for the following: | ||
The wizard will then prompt you for the following: | ||
@@ -50,0 +62,0 @@ - *select mode*: Declare whether you want to scaffold a single component or a library of components. |
318
sfc-init.js
@@ -5,3 +5,3 @@ #! /usr/bin/env node | ||
const fs = require('fs'); | ||
const readlineSync = require('readline-sync'); | ||
const prompts = require('prompts'); | ||
const ejs = require('ejs'); | ||
@@ -31,138 +31,206 @@ | ||
// Prompt whether job is for single component or library of components | ||
console.log('Is this a single component or a library?'); // eslint-disable-line no-console | ||
const modeOptions = [ | ||
'Single Component', | ||
'Library', | ||
]; | ||
const modeIdx = readlineSync.keyInSelect(modeOptions, 'Select one:', { | ||
cancel: false, | ||
}); | ||
const mode = [ | ||
'component', | ||
'library', | ||
][modeIdx]; | ||
// Prompt user for input to populate template files | ||
const npmName = readlineSync.question(`What is the npm name of your ${mode}? `); | ||
let kebabName = kebabcase(npmName); | ||
if (mode === 'component') { | ||
const componentName = readlineSync.question(`What is the kebab-case tag name for your component? (${kebabcase(npmName)}) `, { | ||
defaultInput: kebabcase(npmName), | ||
}); | ||
kebabName = componentName; | ||
// Create cancel function to exit the process | ||
function onCancel() { | ||
// eslint-disable-next-line no-console | ||
console.log('User canceled. Goodbye!'); | ||
process.exit(); | ||
} | ||
const savePath = readlineSync.questionPath(`Enter a location to save the ${mode} files: (./${kebabName}) `, { | ||
defaultInput: path.join(process.cwd(), kebabName), | ||
exists: false, | ||
isDirectory: true, | ||
create: true, | ||
}); | ||
// Stop prompting for input, start processing | ||
const componentNamePascal = pascalify(kebabName); | ||
const vars = { | ||
npmName, | ||
componentNamePascal, | ||
componentName: kebabName, | ||
// Prepare container for response data | ||
const responses = { | ||
mode: '', | ||
npmName: '', | ||
componentName: '', | ||
savePath: '', | ||
}; | ||
const newFiles = { | ||
package: '', | ||
rollupConfig: '', | ||
entryjs: '', | ||
libDev: '', | ||
libExports: '', | ||
component: '', | ||
}; | ||
const paths = { | ||
package: path.join(savePath, 'package.json'), | ||
rollupConfig: path.join(savePath, 'build', 'rollup.config.js'), | ||
entryjs: path.join(savePath, 'src', 'entry.js'), | ||
libDev: null, | ||
libExports: null, | ||
component: null, | ||
}; | ||
// Single component mode | ||
if (mode === 'component') { | ||
newFiles.package = replaceVars( | ||
fs.readFileSync(path.join(__dirname, 'templates', 'single', 'single-package.json')).toString(), | ||
vars, | ||
// Create async prompt functions | ||
async function getMode() { | ||
const question = { | ||
type: 'select', | ||
name: 'mode', | ||
message: 'Is this a single component or a library?', | ||
choices: [ | ||
{ title: 'Single Component', value: 'component' }, | ||
{ title: 'Library', value: 'library' }, | ||
], | ||
initial: 0, | ||
}; | ||
const response = await prompts( | ||
question, | ||
{ onCancel }, | ||
); | ||
newFiles.rollupConfig = replaceVars( | ||
fs.readFileSync(path.join(__dirname, 'templates', 'single', 'build', 'rollup.config.js')).toString(), | ||
vars, | ||
); | ||
newFiles.entryjs = replaceVars( | ||
fs.readFileSync(path.join(__dirname, 'templates', 'single', 'src', 'entry.js')).toString(), | ||
vars, | ||
); | ||
delete newFiles.libDev; | ||
delete newFiles.libExports; | ||
newFiles.component = replaceVars( | ||
fs.readFileSync(path.join(__dirname, 'templates', 'single', 'src', 'component.vue')).toString(), | ||
vars, | ||
); | ||
delete paths.libDev; | ||
delete paths.libExports; | ||
paths.component = path.join(savePath, 'src', `${kebabName}.vue`); | ||
responses.mode = response.mode; | ||
return response.mode; | ||
} | ||
// Library mode | ||
if (mode === 'library') { | ||
newFiles.package = replaceVars( | ||
fs.readFileSync(path.join(__dirname, 'templates', 'library', 'library-package.json')).toString(), | ||
vars, | ||
async function getName(mode) { | ||
let tmpKebabName = ''; | ||
let tmpSavePath = ''; | ||
const questions = [ | ||
{ | ||
type: 'text', | ||
name: 'npmName', | ||
message: `What is the npm name of your ${mode}?`, | ||
validate(val) { | ||
const kebabName = kebabcase(val).trim(); | ||
return (kebabName !== ''); | ||
}, | ||
}, | ||
]; | ||
if (mode === 'component') { | ||
questions.push({ | ||
type: 'text', | ||
name: 'componentName', | ||
message: 'What is the kebab-case tag name for your component?', | ||
initial() { return tmpKebabName; }, | ||
validate(val) { | ||
const kebabName = kebabcase(val).trim(); | ||
return (kebabName !== ''); | ||
}, | ||
}); | ||
} | ||
questions.push({ | ||
type: 'text', | ||
name: 'savePath', | ||
message: `Enter a location to save the ${mode} files:`, | ||
initial() { return `./${tmpSavePath}`; }, | ||
validate: (val) => { | ||
// Validate path does not exist, then create directory | ||
const pathExists = fs.existsSync(val); | ||
return !pathExists; | ||
}, | ||
}); | ||
const response = await prompts( | ||
questions, | ||
{ | ||
onSubmit(prompt, answer) { | ||
if (prompt.name === 'npmName') tmpKebabName = kebabcase(answer).trim(); | ||
if (prompt.name === 'componentName') tmpKebabName = kebabcase(answer).trim(); | ||
tmpSavePath = tmpKebabName; | ||
}, | ||
onCancel, | ||
}, | ||
); | ||
newFiles.rollupConfig = replaceVars( | ||
fs.readFileSync(path.join(__dirname, 'templates', 'library', 'build', 'rollup.config.js')).toString(), | ||
vars, | ||
); | ||
newFiles.entryjs = replaceVars( | ||
fs.readFileSync(path.join(__dirname, 'templates', 'library', 'src', 'entry.js')).toString(), | ||
vars, | ||
); | ||
newFiles.libDev = replaceVars( | ||
fs.readFileSync(path.join(__dirname, 'templates', 'library', 'src', 'lib-dev.vue')).toString(), | ||
vars, | ||
); | ||
newFiles.libExports = replaceVars( | ||
fs.readFileSync(path.join(__dirname, 'templates', 'library', 'src', 'lib-components', 'index.js')).toString(), | ||
vars, | ||
); | ||
newFiles.component = replaceVars( | ||
fs.readFileSync(path.join(__dirname, 'templates', 'library', 'src', 'lib-components', 'component.vue')).toString(), | ||
vars, | ||
); | ||
paths.libDev = path.join(savePath, 'src', 'lib-dev.vue'); | ||
paths.libExports = path.join(savePath, 'src', 'lib-components', 'index.js'); | ||
paths.component = path.join(savePath, 'src', 'lib-components', `${kebabName}-sample.vue`); | ||
responses.npmName = response.npmName; | ||
responses.componentName = response.componentName ? response.componentName : tmpKebabName; | ||
responses.savePath = path.resolve(response.savePath); | ||
return response; | ||
} | ||
Object.keys(paths).forEach((key) => { | ||
ensureDirectoryExists(paths[key]); | ||
fs.writeFileSync(paths[key], newFiles[key]); | ||
}); | ||
// Create function to scaffold based on response data | ||
function scaffold(data) { | ||
// Stop prompting for input, start processing | ||
const componentNamePascal = pascalify(data.componentName); | ||
const vars = { | ||
npmName: data.npmName, | ||
componentNamePascal, | ||
componentName: data.componentName, | ||
}; | ||
const newFiles = { | ||
package: '', | ||
rollupConfig: '', | ||
entryjs: '', | ||
libDev: '', | ||
libExports: '', | ||
component: '', | ||
}; | ||
const paths = { | ||
package: path.join(data.savePath, 'package.json'), | ||
rollupConfig: path.join(data.savePath, 'build', 'rollup.config.js'), | ||
entryjs: path.join(data.savePath, 'src', 'entry.js'), | ||
libDev: null, | ||
libExports: null, | ||
component: null, | ||
}; | ||
// Display completion messages | ||
let completeMessage; | ||
if (mode === 'component') { | ||
completeMessage = ` | ||
Init is complete, your files have been generated and saved into the directory you specified above. | ||
Within that directory, use src/${kebabName}.vue as a starting point for your SFC. | ||
When you're ready, run \`npm run build\` to generate the redistributable versions. | ||
// Single component mode | ||
if (data.mode === 'component') { | ||
newFiles.package = replaceVars( | ||
fs.readFileSync(path.join(__dirname, 'templates', 'single', 'single-package.json')).toString(), | ||
vars, | ||
); | ||
newFiles.rollupConfig = replaceVars( | ||
fs.readFileSync(path.join(__dirname, 'templates', 'single', 'build', 'rollup.config.js')).toString(), | ||
vars, | ||
); | ||
newFiles.entryjs = replaceVars( | ||
fs.readFileSync(path.join(__dirname, 'templates', 'single', 'src', 'entry.js')).toString(), | ||
vars, | ||
); | ||
delete newFiles.libDev; | ||
delete newFiles.libExports; | ||
newFiles.component = replaceVars( | ||
fs.readFileSync(path.join(__dirname, 'templates', 'single', 'src', 'component.vue')).toString(), | ||
vars, | ||
); | ||
delete paths.libDev; | ||
delete paths.libExports; | ||
paths.component = path.join(data.savePath, 'src', `${data.componentName}.vue`); | ||
} | ||
`; | ||
// Library mode | ||
if (data.mode === 'library') { | ||
newFiles.package = replaceVars( | ||
fs.readFileSync(path.join(__dirname, 'templates', 'library', 'library-package.json')).toString(), | ||
vars, | ||
); | ||
newFiles.rollupConfig = replaceVars( | ||
fs.readFileSync(path.join(__dirname, 'templates', 'library', 'build', 'rollup.config.js')).toString(), | ||
vars, | ||
); | ||
newFiles.entryjs = replaceVars( | ||
fs.readFileSync(path.join(__dirname, 'templates', 'library', 'src', 'entry.js')).toString(), | ||
vars, | ||
); | ||
newFiles.libDev = replaceVars( | ||
fs.readFileSync(path.join(__dirname, 'templates', 'library', 'src', 'lib-dev.vue')).toString(), | ||
vars, | ||
); | ||
newFiles.libExports = replaceVars( | ||
fs.readFileSync(path.join(__dirname, 'templates', 'library', 'src', 'lib-components', 'index.js')).toString(), | ||
vars, | ||
); | ||
newFiles.component = replaceVars( | ||
fs.readFileSync(path.join(__dirname, 'templates', 'library', 'src', 'lib-components', 'component.vue')).toString(), | ||
vars, | ||
); | ||
paths.libDev = path.join(data.savePath, 'src', 'lib-dev.vue'); | ||
paths.libExports = path.join(data.savePath, 'src', 'lib-components', 'index.js'); | ||
paths.component = path.join(data.savePath, 'src', 'lib-components', `${data.componentName}-sample.vue`); | ||
} | ||
Object.keys(paths).forEach((key) => { | ||
ensureDirectoryExists(paths[key]); | ||
fs.writeFileSync(paths[key], newFiles[key]); | ||
}); | ||
// Display completion messages | ||
let completeMessage; | ||
if (data.mode === 'component') { | ||
completeMessage = ` | ||
Init is complete, your files have been generated and saved into the directory you specified above. | ||
Within that directory, use src/${data.componentName}.vue as a starting point for your SFC. | ||
When you're ready, run \`npm run build\` to generate the redistributable versions. | ||
`; | ||
} | ||
if (data.mode === 'library') { | ||
completeMessage = ` | ||
Init is complete, your files have been generated and saved into the directory you specified above. | ||
Within that directory, you will find a sample SFC at src/lib-components/${data.componentName}-sample.vue. | ||
Any components you wish to expose as part of your library should be saved in that directory, and | ||
an entry must be added to src/lib-components/index.js so that rollup is aware of it. When you're | ||
ready, run \`npm run build\` to generate the redistributable versions. | ||
`; | ||
} | ||
// eslint-disable-next-line no-console | ||
console.log(completeMessage); | ||
} | ||
if (mode === 'library') { | ||
completeMessage = ` | ||
Init is complete, your files have been generated and saved into the directory you specified above. | ||
Within that directory, you will find a sample SFC at src/lib-components/${kebabName}-sample.vue. | ||
Any components you wish to expose as part of your library should be saved in that directory, and | ||
an entry must be added to src/lib-components/index.js so that rollup is aware of it. When you're | ||
ready, run \`npm run build\` to generate the redistributable versions. | ||
`; | ||
} | ||
// eslint-disable-next-line no-console | ||
console.log(completeMessage); | ||
// Begin asking for input, then scaffold | ||
getMode() | ||
.then(getName) | ||
.then(() => { | ||
scaffold(responses); | ||
}); |
// rollup.config.js | ||
import vue from 'rollup-plugin-vue'; | ||
import buble from 'rollup-plugin-buble'; | ||
import commonjs from 'rollup-plugin-commonjs'; | ||
import replace from 'rollup-plugin-replace'; | ||
@@ -20,2 +21,3 @@ import uglify from 'rollup-plugin-uglify-es'; | ||
}), | ||
commonjs(), | ||
vue({ | ||
@@ -22,0 +24,0 @@ css: true, |
@@ -29,10 +29,11 @@ { | ||
"minimist": "^1.2.0", | ||
"rollup": "^0.67.4", | ||
"rollup": "^1.1.2", | ||
"rollup-plugin-buble": "^0.19.6", | ||
"rollup-plugin-commonjs": "^9.2.0", | ||
"rollup-plugin-replace": "^2.1.0", | ||
"rollup-plugin-uglify-es": "0.0.1", | ||
"rollup-plugin-vue": "4.3.2", | ||
"vue": "^2.5.21", | ||
"vue-template-compiler": "^2.5.21" | ||
"rollup-plugin-vue": "^4.6.2", | ||
"vue": "^2.5.22", | ||
"vue-template-compiler": "^2.5.22" | ||
} | ||
} |
// rollup.config.js | ||
import vue from 'rollup-plugin-vue'; | ||
import buble from 'rollup-plugin-buble'; | ||
import commonjs from 'rollup-plugin-commonjs'; | ||
import replace from 'rollup-plugin-replace'; | ||
@@ -20,2 +21,3 @@ import uglify from 'rollup-plugin-uglify-es'; | ||
}), | ||
commonjs(), | ||
vue({ | ||
@@ -22,0 +24,0 @@ css: true, |
@@ -31,10 +31,11 @@ { | ||
"minimist": "^1.2.0", | ||
"rollup": "^0.67.4", | ||
"rollup": "^1.1.2", | ||
"rollup-plugin-buble": "^0.19.6", | ||
"rollup-plugin-commonjs": "^9.2.0", | ||
"rollup-plugin-replace": "^2.1.0", | ||
"rollup-plugin-uglify-es": "0.0.1", | ||
"rollup-plugin-vue": "4.3.2", | ||
"vue": "^2.5.21", | ||
"vue-template-compiler": "^2.5.21" | ||
"rollup-plugin-vue": "^4.6.2", | ||
"vue": "^2.5.22", | ||
"vue-template-compiler": "^2.5.22" | ||
} | ||
} |
24142
350
90
+ Addedprompts@^2.0.1
+ Addedkleur@3.0.3(transitive)
+ Addedprompts@2.4.2(transitive)
+ Addedsisteransi@1.0.5(transitive)
- Removedreadline-sync@^1.4.9
- Removedreadline-sync@1.4.10(transitive)