Skip to content

Commit

Permalink
feat:create-app
Browse files Browse the repository at this point in the history
  • Loading branch information
jerryYuX committed Jul 14, 2021
1 parent 42fa474 commit 4268fa2
Show file tree
Hide file tree
Showing 19 changed files with 320 additions and 27 deletions.
195 changes: 195 additions & 0 deletions packages/create-app/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@
#!/usr/bin/env node
/* eslint-disable no-console */
/* eslint-disable array-callback-return */

// @ts-check
const fs = require('fs');
const path = require('path');
const argv = require('minimist')(process.argv.slice(2));
const { prompt } = require('enquirer');
const { cyan } = require('kolorist');

const cwd = process.cwd();

const TEMPLATES = [
{
name: 'react-admin-ts',
color: cyan,
},
];

function copy(src, dest) {
const stat = fs.statSync(src);
if (stat.isDirectory()) {
fs.mkdirSync(dest, { recursive: true });
const list = fs.readdirSync(src);
list.map((item) => {
const srcFile = path.resolve(src, item);
const destFile = path.resolve(dest, item);
copy(srcFile, destFile);
});
} else {
fs.copyFileSync(src, dest);
}
}

function emptyDir(dir) {
if (!fs.existsSync(dir)) {
return;
}
const list = fs.readdirSync(dir);
list.map((item) => {
const abs = path.resolve(dir, item);
if (fs.lstatSync(abs).isDirectory()) {
emptyDir(abs);
fs.rmdirSync(abs);
} else {
fs.unlinkSync(abs);
}
});
}
const renameFiles = {
_gitignore: '.gitignore',
};

async function getValidPackageName(projectName) {
const packageNameRegExp = /^(?:@[a-z0-9-*~][a-z0-9-*._~]*\/)?[a-z0-9-~][a-z0-9-._~]*$/;
if (packageNameRegExp.test(projectName)) {
return projectName;
}
const suggestedPackageName = projectName
.trim()
.toLowerCase()
.replace(/\s+/g, '-')
.replace(/^[._]/, '')
.replace(/[^a-z0-9-~]+/g, '-');

/**
* @type {{ inputPackageName: string }}
*/
const { inputPackageName } = await prompt({
type: 'input',
name: 'inputPackageName',
message: `Package name:`,
initial: suggestedPackageName,
validate: (input) => (packageNameRegExp.test(input) ? true : 'Invalid package.json name'),
});
return inputPackageName;
}

async function init() {
let targetDir = argv._[0];
if (!targetDir) {
/**
* @type {{ projectName: string }}
*/
const { projectName } = await prompt({
type: 'input',
name: 'projectName',
message: `Project name:`,
initial: 'viter-project',
});
targetDir = projectName;
}
const packageName = await getValidPackageName(targetDir);
const root = path.join(cwd, targetDir);

if (!fs.existsSync(root)) {
fs.mkdirSync(root, { recursive: true });
} else {
const existing = fs.readdirSync(root);
if (existing.length) {
/**
* @type {{ yes: boolean }}
*/
const { yes } = await prompt({
type: 'confirm',
name: 'yes',
initial: 'Y',
message:
`${
targetDir === '.' ? 'Current directory' : `Target directory ${targetDir}`
// eslint-disable-next-line no-useless-concat
} is not empty.\n` + `Remove existing files and continue?`,
});
if (yes) {
emptyDir(root);
} else {
return;
}
}
}

// determine template
let selectTemplate = argv.t || argv.template;
const message = 'Select a framework:';
const isValidTemplate = false;

if (!selectTemplate || !isValidTemplate) {
/**
* @type {{ framework: string }}
*/
// @ts-ignore
const { template } = await prompt({
type: 'select',
name: 'template',
message,
format(name) {
const ITEMPLATES = TEMPLATES.find((v) => v.name === name);
return ITEMPLATES ? ITEMPLATES.color(ITEMPLATES.display || ITEMPLATES.name) : name;
},
choices: TEMPLATES.map((f) => ({
name: f.name,
value: f.name,
message: f.color(f.display || f.name),
})),
});
console.log(template);
selectTemplate = template;
}

console.log(`\nScaffolding project in ${root}...`);

const templateDir = path.join(__dirname, `template-${selectTemplate}`);

const write = (file, content) => {
const targetPath = renameFiles[file]
? path.join(root, renameFiles[file])
: path.join(root, file);
if (content) {
fs.writeFileSync(targetPath, content);
} else {
copy(path.join(templateDir, file), targetPath);
}
};

const files = fs.readdirSync(templateDir);

files
.filter((f) => f !== 'package.json')
.map((file) => {
write(file);
return file;
});

// eslint-disable-next-line
const pkg = require(path.join(templateDir, `package.json`));

pkg.name = packageName;

write('package.json', JSON.stringify(pkg, null, 2));

const pkgManager = /yarn/.test(process.env.npm_execpath) ? 'yarn' : 'npm';

console.log(`\nDone. Now run:\n`);
if (root !== cwd) {
console.log(` cd ${path.relative(cwd, root)}`);
}
console.log(` ${pkgManager === 'yarn' ? `yarn` : `npm install`}`);
console.log(` ${pkgManager === 'yarn' ? `yarn dev` : `npm run dev`}`);
console.log();
}

init().catch((e) => {
console.error(e);
});
27 changes: 15 additions & 12 deletions packages/create-app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,31 +5,34 @@
"keywords": [
"vitejs"
],
"author": "suanmei <mr_suanmei@163.com>",
"author": "jerryYuX <1342985759@qq.com>",
"homepage": "https://github.com/ykfe/viter",
"license": "MIT",
"main": "dist/index.js",
"directories": {
"dist": "dist"
},
"files": [
"dist"
],
"bin": "index.js",

"repository": {
"type": "git",
"url": "git+https://github.com/ykfe/viter.git"
"url": "git+https://github.com/ykfe/viter.git",
"directory": "packages/create-app"
},
"engines": {
"node": ">=12.0.0"
},
"scripts": {
"prepublishOnly": "node scripts/prepublish.js",
"lint-eslint": "eslint --cache --ext .ts,.tsx ./src",
"check-types": "tsc --noEmit",
"lint": "npm run lint-eslint & npm run check-types",
"declare-type": "tsc --emitDeclarationOnly",
"build": "rollup -c & npm run declare-type",
"watch": "watch 'npm run build' ./src"
"dev": "node ./index.js"
},
"bugs": {
"url": "https://github.com/ykfe/viter/issues"
},
"gitHead": "70b767d3d88f7df4d22502d44c51ae664910a763"
"gitHead": "70b767d3d88f7df4d22502d44c51ae664910a763",
"dependencies": {
"enquirer": "^2.3.6",
"kolorist": "^1.2.9",
"minimist": "^1.2.5"
}
}
2 changes: 0 additions & 2 deletions packages/create-app/src/a.ts

This file was deleted.

5 changes: 0 additions & 5 deletions packages/create-app/src/index.ts

This file was deleted.

14 changes: 14 additions & 0 deletions packages/create-app/template-react-admin-ts/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="src/favicon.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite App</title>
</head>
<body>
<div id="root"></div>
{# 入口路径,中后台项目非必要不修改 #}
<script type="module" src="./src/.viter/entry.tsx"></script>
</body>
</html>
21 changes: 21 additions & 0 deletions packages/create-app/template-react-admin-ts/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"name": "viter-template",
"version": "0.0.0",
"scripts": {
"dev": "vite --config viter.config.ts",
"build": "tsc && vite build",
"serve": "vite preview"
},
"dependencies": {
"react": "^17.0.0",
"react-dom": "^17.0.0",
"viter": "^0.2.0"
},
"devDependencies": {
"@types/react": "^17.0.0",
"@types/react-dom": "^17.0.0",
"@vitejs/plugin-react-refresh": "^1.3.1",
"typescript": "^4.1.2",
"vite": "^2.1.3"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import React from 'react';

function Component() {
return (
<div>
Component
</div>
);
}

export default Component;
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import React from "react";

function Layout(props) {
return <div>{props.children}</div>;
}

export default Layout;
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import React from 'react';

function TestA() {
return (
<div>
TestA
</div>
);
}

export default TestA;
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import React from 'react';

function TestB() {
return (
<div>
TestB
</div>
);
}

export default TestB;
20 changes: 20 additions & 0 deletions packages/create-app/template-react-admin-ts/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"compilerOptions": {
"target": "ESNext",
"lib": ["DOM", "DOM.Iterable", "ESNext"],
"types": ["vite/client"],
"allowJs": false,
"skipLibCheck": false,
"esModuleInterop": false,
"allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"module": "ESNext",
"moduleResolution": "Node",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react"
},
"include": ["./src"]
}
8 changes: 8 additions & 0 deletions packages/create-app/template-react-admin-ts/viter.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { defineConfig } from 'vite';
import reactRefresh from '@vitejs/plugin-react-refresh';
const { resolve } = require('path');
console.log(__dirname);
// https://vitejs.dev/config/
export default defineConfig({
plugins: [reactRefresh()],
});
3 changes: 2 additions & 1 deletion packages/create-app/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
{
"extends": "../../tsconfig",
"compilerOptions": {
"outDir": "dist/types"
"outDir": "dist/types",
"types": ["node"]
},
"include": ["./src", "./types"]
}
1 change: 0 additions & 1 deletion packages/renderer/src/generateInitFiles/routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { readFileSync } from 'fs';
import { resolve } from 'path';
import _cloneDeep from 'lodash/cloneDeep';
import { writeFile, generateRandomStr } from '../utils/index';

// eslint-disable-next-line @typescript-eslint/no-var-requires
const ArtTemplate = require('art-template');

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from 'react';
import { BrowserRouter } from 'react-router-dom';
import { BrowserRouter } from '@viter/runtime';
import Routes from './routes'
export default function renderRouter() {
return (
Expand Down
Loading

0 comments on commit 4268fa2

Please sign in to comment.