Skip to content

Commit

Permalink
feat: first implementation of generator
Browse files Browse the repository at this point in the history
  • Loading branch information
whatsaaaa committed Apr 2, 2021
1 parent 17f4248 commit 94d2223
Show file tree
Hide file tree
Showing 14 changed files with 438 additions and 5 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
"devDependencies": {
"@commitlint/cli": "^12.1.1",
"@commitlint/config-conventional": "^12.1.1",
"ejs": "^3.1.6",
"eslint": "^7.23.0",
"generate-changelog": "^1.8.0",
"husky": "^6.0.0"
Expand Down
75 changes: 71 additions & 4 deletions plugin-init.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ const pkg = require("./package");
// Object to store data from user input response.
const result = {
version: "",
pluginName: "",
npmName: "",
componentName: "",
language: "",
update: false
}
Expand Down Expand Up @@ -58,13 +59,14 @@ async function getVersion() {
async function getName() {
const question = {
type: "text",
name: "pluginName",
name: "npmName",
message: "What is the name of your Vue plugin?"
};
const response = await prompts(question, {
onCancel: onCancel
});
result.pluginName = response.pluginName;
result.npmName = response.npmName;
result.componentName = response.npmName;
}

async function getLanguage() {
Expand All @@ -84,10 +86,75 @@ async function getLanguage() {
result.language = response.language;
}

function createPluginProject(options) {
const vars = {
npmName: options.npmName,
componentName: options.componentName,
version: options.version,
ts: options.language === "ts"
};

const files = {
common: [
"build/rollup.config.js",
{ "src/entry.esm.ts": `src/entry.esm.${data.language}` },
{ "src/entry.ts": `src/entry.${data.language}` },
{ "dev/serve.ts": `dev/serve.${data.language}` },
"dev/serve/vue",
".browserslistrc",
"babel.config.js",
(data.language === "ts" && data.version === 2) ? "shims-tsx.d.ts" : null,
(data.language === "ts") ? "shims-vue.d.ts" : null,
(data.language === "ts") ? "tsconfig.json" : null,
{ "plugin-package.json": "package.json" }
]
}

const fileActions = [
...files.common.filter((entry) => entry)
];

fileActions.forEach((fileAction) => {
let srcPath;
let destPath;

if (typeof fileAction === "string") {
srcPath = fileAction;
destPath = fileAction;
} else {
[[srcPath, destPath]] = Object.entries(entry);
}

srcPath = path.join.apply(null, [
__dirname,
"templates",
"plugin",
...srcPath.split("/")
]);

destPath = path.join.apply(null, [
data.componentName,
...destPath.split("/")
]);

ensureDirectoryExists(destPath);
fs.writeFileSync(destPath, ejs.render(fs.readFileSync(srcPath).toString(), vars));
});
}

const ensureDirectoryExists = (filePath) => {
const dirname = path.dirname(filePath);
if (fs.existsSync(dirname)) {
return true;
}
ensureDirectoryExists(dirname);
return fs.mkdirSync(dirname);
};

checkForCliToolUpdate()
.then(getVersion)
.then(getName)
.then(getLanguage)
.then(() => {
console.log("Result: ", result);
createPluginProject(result);
});
3 changes: 3 additions & 0 deletions templates/plugin/.browserslistrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
current node
last 2 versions and > 2%
ie > 10
5 changes: 5 additions & 0 deletions templates/plugin/babel.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
const devPresets = ["@vue/babel-preset-app"];
const buildPresets = ["@babel/preset-env"<% if (ts) { -%>, "@babel/preset-typescript"<% } -%>];
module.exports = {
presets: (process.env.NODE_ENV === "development" ? devPresets : buildPresets),
};
125 changes: 125 additions & 0 deletions templates/plugin/build/rollup.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
// rollup.config.js
import fs from 'fs';
import path from 'path';
import vue from 'rollup-plugin-vue';
import alias from '@rollup/plugin-alias';
import commonjs from '@rollup/plugin-commonjs';
import resolve from '@rollup/plugin-node-resolve';
import replace from '@rollup/plugin-replace';
import babel from '@rollup/plugin-babel';
<% if (version === 3) { -%>
import PostCSS from 'rollup-plugin-postcss';
<% } -%>
import { terser } from 'rollup-plugin-terser';
import minimist from 'minimist';

// Get browserslist config and remove ie from es build targets
const esbrowserslist = fs.readFileSync('./.browserslistrc')
.toString()
.split('\n')
.filter((entry) => entry && entry.substring(0, 2) !== 'ie');

const argv = minimist(process.argv.slice(2));

const projectRoot = path.resolve(__dirname, '..');

const baseConfig = {
input: 'src/entry.<% if (ts) {%>ts<% } else { %>js<% } %>',
plugins: {
preVue: [
alias({
entries: [
{
find: '@',
replacement: `${path.resolve(projectRoot, 'src')}`,
},
],
}),
],
replace: {
'process.env.NODE_ENV': JSON.stringify('production'),
},
vue: {
<% if (version === 2) { -%>
css: true,
template: {
isProduction: true,
},
<% } -%>
},
postVue: [
resolve({
extensions: ['.js', '.jsx', '.ts', '.tsx', '.vue'],
}),
<% if (version === 3) { -%>
// Process only `<style module>` blocks.
PostCSS({
modules: {
generateScopedName: '[local]___[hash:base64:5]',
},
include: /&module=.*\.css$/,
}),
// Process all `<style>` blocks except `<style module>`.
PostCSS({ include: /(?<!&module=.*)\.css$/ }),
<% } -%>
],
babel: {
exclude: 'node_modules/**',
extensions: ['.js', '.jsx', '.ts', '.tsx', '.vue'],
babelHelpers: 'bundled',
},
},
};

// ESM/UMD/IIFE shared settings: externals
// Refer to https://rollupjs.org/guide/en/#warning-treating-module-as-external-dependency
const external = [
// list external dependencies, exactly the way it is written in the import statement.
// eg. 'jquery'
'vue',
];

// UMD/IIFE shared settings: output.globals
// Refer to https://rollupjs.org/guide/en#output-globals for details
const globals = {
// Provide global variable names to replace your external imports
// eg. jquery: '$'
vue: 'Vue',
};

// Customize configs for individual targets
const buildFormats = [];
if (!argv.format || argv.format === 'es') {
const esConfig = {
...baseConfig,
input: 'src/entry.esm.<% if (ts) {%>ts<% } else { %>js<% } %>',
external,
output: {
file: 'dist/<%-componentName%>.esm.js',
format: 'esm',
exports: 'named',
},
plugins: [
replace(baseConfig.plugins.replace),
...baseConfig.plugins.preVue,
vue(baseConfig.plugins.vue),
...baseConfig.plugins.postVue,
babel({
...baseConfig.plugins.babel,
presets: [
[
'@babel/preset-env',
{
targets: esbrowserslist,
},
],
],
}),
commonjs(),
],
};
buildFormats.push(esConfig);
}

// Export config
export default buildFormats;
24 changes: 24 additions & 0 deletions templates/plugin/dev/serve.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<% if (version === 3) { -%>
import { createApp } from "vue";
import Dev from "./serve.vue";

const app = createApp(Dev);
app.mount("#app");
<% } else {
if (ts) { -%>
import Vue, { VNode } from "vue";
<% } else { -%>
import Vue from "vue";
<% } -%>
import Dev from "./serve.vue";

Vue.config.productionTip = false;

new Vue({
<% if (ts) { -%>
render: (h): VNode => h(Dev),
<% } else { -%>
render: (h) => h(Dev),
<% } -%>
}).$mount("#app");
<% } -%>
17 changes: 17 additions & 0 deletions templates/plugin/dev/serve.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<script<% if (ts) { %> lang="ts"<% } %>>
<% if (version === 3) { -%>
import { defineComponent } from "vue";
<% } else { -%>
import Vue from "vue";
<% } -%>
export default <% if (version === 3) {%>defineComponent<% } else { %>Vue.extend<% } %>({
name: "ServeDev",
});
</script>

<template>
<div id="app">
Hello, World
</div>
</template>
81 changes: 81 additions & 0 deletions templates/plugin/plugin-package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
{
"name": "<%-npmName>",
"version": "0.0.1",
"description": "",
"main": "dist/<%-npmName%>/esm.js",
"browser": "dist/<%-npmName%>/esm.js",
"module": "dist/<%-npmName%>/esm.js",
<% if (ts) { -%>
"types": "<%-npmName%>.d.ts",
<% } -%>
"files": [
"dist/*",
<% if (ts) { -%>
"<%-npmName%>.d.ts",
<% } -%>
"src/**/*.vue"
],
"sideEffects": false,
"scripts": {
"serve": "vue-cli-service serve dev/serve.<% if (ts) { %>ts<% } else { %>js<% } %>",
"build": "cross-env NODE_ENV=production rollup --config build/rollup.config.js",
"build:ssr": "cross-env NODE_ENV=production rollup --config build/rollup.config.js --format cjs",
"build:es": "cross-env NODE_ENV=production rollup --config build/rollup.config.js --format es",
"build:unpkg": "cross-env NODE_ENV=production rollup --config build/rollup.config.js --format iife"
},
"dependencies": {},
"devDependencies": {
"@babel/core": "^7.12.10",
"@babel/preset-env": "^7.12.11",
<% if (ts) { -%>
"@babel/preset-typescript": "^7.12.7",
<% } -%>
"@rollup/plugin-alias": "^3.1.1",
"@rollup/plugin-babel": "^5.2.2",
"@rollup/plugin-commonjs": "^17.0.0",
"@rollup/plugin-node-resolve": "^11.0.1",
"@rollup/plugin-replace": "^2.3.4",
"@vue/cli-plugin-babel": "^4.5.10",
<% if (ts) { -%>
"@vue/cli-plugin-typescript": "^4.5.10",
<% } -%>
"@vue/cli-service": "^4.5.10",
<% if (version === 3) { -%>
"@vue/compiler-sfc": "^3.0.5",
<% } -%>
"cross-env": "^7.0.3",
"minimist": "^1.2.5",
<% if (version === 3) { -%>
"postcss": "^8.2.3",
<% } -%>
"rollup": "^2.36.1",
<% if (version === 3) { -%>
"rollup-plugin-postcss": "^4.0.0",
<% } -%>
"rollup-plugin-terser": "^7.0.2",
<% if (version === 3) { -%>
"rollup-plugin-vue": "^6.0.0",
<% } else { -%>
"rollup-plugin-vue": "^5.1.9",
<% } -%>
<% if (ts) { -%>
"typescript": "^3.8.3",
<% } -%>
<% if (version === 3) { -%>
"vue": "^3.0.5"
<% } else { -%>
"vue": "^2.6.12",
"vue-template-compiler": "^2.6.12"
<% } -%>
},
"peerDependecies": {
<% if (version === 3) { -%>
"vue": "^3.0.5"
<% } else { -%>
"vue": "^2.6.12"
<% } -%>
},
"engines": {
"node": ">=12"
}
}
11 changes: 11 additions & 0 deletions templates/plugin/shims-tsx.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import Vue, { VNode } from "vue";

declare global {
namespace JSX {
interface Element extends VNode {}
interface ElementClass extends Vue {}
interface IntrinsicElements {
[elem: string]: any
}
}
}
11 changes: 11 additions & 0 deletions templates/plugin/shims-vue.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
declare module "*.vue" {
<% if (version === 3) { -%>
import { DefineComponent } from "vue";

const Component: DefineComponent<{}, {}, any>;
export default Component;
<% } else { -%>
import Vue from "vue";
export default Vue;
<% } -%>
}
Loading

0 comments on commit 94d2223

Please sign in to comment.