UNPKG

@gdjiami/cli

Version:

CLI for build front end project.

257 lines (256 loc) 11.5 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); /** * create project */ var path_1 = tslib_1.__importDefault(require("path")); var chalk_1 = tslib_1.__importDefault(require("chalk")); var fs_extra_1 = tslib_1.__importDefault(require("fs-extra")); var ignore_1 = tslib_1.__importDefault(require("ignore")); var validate_npm_package_name_1 = tslib_1.__importDefault(require("validate-npm-package-name")); var semver_1 = tslib_1.__importDefault(require("semver")); var child_process_1 = require("child_process"); var pickBy_1 = tslib_1.__importDefault(require("lodash/pickBy")); var utils_1 = require("../../utils"); var getTemplate_1 = tslib_1.__importDefault(require("./getTemplate")); var genGitignore_1 = tslib_1.__importDefault(require("./genGitignore")); var genGlobalDeclaration_1 = tslib_1.__importDefault(require("./genGlobalDeclaration")); var genVscodeSettings_1 = tslib_1.__importDefault(require("./genVscodeSettings")); var genESlintConfig_1 = tslib_1.__importDefault(require("./genESlintConfig")); var genTsConfig_1 = tslib_1.__importDefault(require("./genTsConfig")); var genPrettier_1 = tslib_1.__importDefault(require("./genPrettier")); var useYarn = utils_1.shouldUseYarn(); var builinDevDependencies = [ // format 'prettier', 'pretty-quick', 'husky', '@types/webpack-env', '@types/react-hot-loader', ]; /** * 检查是否是合法的npm包名 * @param name */ function validatePackageName(name) { var res = validate_npm_package_name_1.default(name); if (!res.validForNewPackages) { utils_1.message.error("Could not create a project called " + chalk_1.default.red(name) + " because of npm naming restrictions:"); printValidationResults(res.errors); printValidationResults(res.warnings); process.exit(1); } } function printValidationResults(results) { if (typeof results !== 'undefined') { results.forEach(function (error) { console.error(chalk_1.default.red(" * " + error)); }); } } function ensureAppPath(appPath) { if (fs_extra_1.default.existsSync(appPath)) { var name = path_1.default.basename(appPath); utils_1.message.error("Could not create a project called " + name + ", directory existed."); process.exit(1); } fs_extra_1.default.ensureDirSync(appPath); } /** * clone files from templatePath to appPath, * default it will ignore `node_modules`, `dist` and `yarn.*`, `.git` etc * Template developer also define `.template-ignore` to add ignore rules * .gitignore will automatic recognized by npm * @param templatePath * @param appPath */ function cloneTemplate(templatePath, appPath) { var ig = ignore_1.default(); var defaultIgnore = ['node_modules', 'dist', 'yarn.*', '.git', '.template-ignore', '.cache-loader']; ig.add(defaultIgnore); var templateIgnorePath = path_1.default.join(templatePath, '.template-ignore'); if (fs_extra_1.default.existsSync(templateIgnorePath)) { ig.add(fs_extra_1.default.readFileSync(templateIgnorePath).toString()); } fs_extra_1.default.copySync(templatePath, appPath, { overwrite: false, errorOnExist: false, dereference: true, filter: function (src) { var relativePath = path_1.default.relative(templatePath, src); if (relativePath === '') { return true; } return !ig.ignores(relativePath); }, }); } function transformDependencies(org) { return Object.keys(org).map(function (key) { if (org[key] === '*') { return key; } return key + "@" + org[key]; }); } function initialPackageJson(appPath, templatePath, ownPath, argv) { var name = argv.name, binName = argv.binName, cliName = argv.cliName, cliVersion = argv.cliVersion; var reservedProperties = { name: name, version: '0.1.0', private: true, dependencies: {}, devDependencies: {}, scripts: { start: binName + " start", build: binName + " build", serve: binName + " serve", analyze: binName + " analyze", }, // prettier format husky: { hooks: { 'pre-commit': 'pretty-quick --staged', }, }, }; var optionalProperties = { jm: { // proxy config, can use template variable in .env.* proxy: {}, // for antd, antd-mobile importPlugin: [], }, browserslist: 'last 2 versions', optionalDependencies: {}, }; var pacakgeJson = tslib_1.__assign(tslib_1.__assign({}, reservedProperties), optionalProperties); var templatePackageJson = path_1.default.join(templatePath, 'package.json'); if (fs_extra_1.default.existsSync(templatePackageJson)) { var pkg = require(templatePackageJson); if (pkg.dependencies) { pacakgeJson.dependencies = tslib_1.__assign(tslib_1.__assign({}, pacakgeJson.dependencies), pkg.dependencies); } if (pkg.devDependencies) { pacakgeJson.devDependencies = tslib_1.__assign(tslib_1.__assign({}, pacakgeJson.devDependencies), pkg.devDependencies); } if (pkg.scripts) { pacakgeJson.scripts = tslib_1.__assign(tslib_1.__assign({}, pacakgeJson.scripts), pkg.scripts); } // 合并package.json var includeFields_1 = pkg.includeFields || []; var pickedPkg = pickBy_1.default(pkg, function (value, key) { return key in optionalProperties || key.startsWith('jm') || includeFields_1.indexOf(key) !== -1; }); pacakgeJson = tslib_1.__assign(tslib_1.__assign({}, pacakgeJson), pickedPkg); } // install cli commands var packageToInstall = cliName; cliVersion = cliVersion || pacakgeJson.devDependencies[cliName]; delete pacakgeJson.devDependencies[cliName]; if (cliVersion) { var validSemver = semver_1.default.valid(cliVersion); if (validSemver) { packageToInstall += "@" + validSemver; } } cloneTemplate(templatePath, appPath); utils_1.writeJSON(path_1.default.join(appPath, 'package.json'), pacakgeJson); utils_1.message.info("Installing pacakges. This might take a couple of minutes."); var devdependencies = builinDevDependencies .filter(function (dep) { return !(dep in pacakgeJson.dependencies) && !(dep in pacakgeJson.devDependencies); }) .concat(transformDependencies(pacakgeJson.devDependencies)); var dependencies = transformDependencies(pacakgeJson.dependencies); devdependencies.push(packageToInstall); var dependenciesInstallCommand; var devDependenciesInstallCommand; if (useYarn) { var command = 'yarnpkg'; dependenciesInstallCommand = command + " add " + dependencies.join(' ') + " -s"; devDependenciesInstallCommand = command + " add " + devdependencies.join(' ') + " --dev -s"; } else { var command = 'npm'; dependenciesInstallCommand = command + " install " + dependencies.join(' ') + " --save"; devDependenciesInstallCommand = command + " install " + devdependencies.join(' ') + " --save-dev"; } utils_1.message.info(chalk_1.default.cyan("Installing dependencies...")); child_process_1.execSync(dependenciesInstallCommand, { stdio: 'inherit' }); utils_1.message.info(chalk_1.default.cyan("Installing devdependencies...")); child_process_1.execSync(devDependenciesInstallCommand, { stdio: 'inherit' }); } function tryInitialGit(appPath) { try { child_process_1.execSync('git init', { stdio: 'ignore' }); return true; } catch (e) { return false; } } function firstCommit() { try { child_process_1.execSync('git add -A', { stdio: 'ignore' }); child_process_1.execSync('git commit -m "Initial commit from jm-cli"', { stdio: 'ignore', }); } catch (_a) { // ignore } } /** * welcome infomation */ function welcome(args) { var cmd = useYarn ? 'yarn' : 'npm'; console.log("\n\u2728 Success! Created " + chalk_1.default.blue(args.name) + " at " + chalk_1.default.cyan(args.appPath) + "\nInside that directory, you can run several commands:\n\n " + chalk_1.default.green(cmd + " start") + " " + chalk_1.default.gray("# Starts the development server.") + "\n " + chalk_1.default.green(cmd + " build") + " " + chalk_1.default.gray("# Bundles the app into static files for production.") + "\n " + chalk_1.default.green(cmd + " serve") + " " + chalk_1.default.gray("# Serve production bundle in 'dist'") + "\n " + chalk_1.default.green(cmd + " analyze") + " " + chalk_1.default.gray("# Analyze webpack bundle for production") + "\n\nTyping " + chalk_1.default.green("cd " + args.name) + " to start code happily.\n "); } /** * @param cwd 当前工作目录 * @param originalDirname cli项目根目录 * @param argv 命令参数 */ exports.default = (function (cwd, originalDirname, argv) { return tslib_1.__awaiter(void 0, void 0, void 0, function () { var name, version, template, templatePath, appPath, gitInitialed, ownPackageJson, generators; return tslib_1.__generator(this, function (_a) { switch (_a.label) { case 0: utils_1.message.info("Creating a new React Project in " + chalk_1.default.green(cwd) + "\n"); name = argv.name, version = argv.version, template = argv.template; validatePackageName(name); return [4 /*yield*/, getTemplate_1.default(!!argv.force, originalDirname, cwd, template)]; case 1: templatePath = _a.sent(); if (!fs_extra_1.default.existsSync(templatePath)) { utils_1.message.error("Template path " + templatePath + " not existed."); process.exit(1); } appPath = path_1.default.join(cwd, name); ensureAppPath(appPath); process.chdir(appPath); gitInitialed = tryInitialGit(appPath); if (gitInitialed) { utils_1.message.info('Initialized a git repository.'); } ownPackageJson = require(path_1.default.join(originalDirname, 'package.json')); initialPackageJson(appPath, templatePath, originalDirname, { name: name, cliName: ownPackageJson.name, cliVersion: version, binName: Object.keys(ownPackageJson.bin)[0], }); generators = [genTsConfig_1.default, genESlintConfig_1.default, genVscodeSettings_1.default, genGlobalDeclaration_1.default, genGitignore_1.default, genPrettier_1.default]; generators.forEach(function (g) { return g(appPath, originalDirname, ownPackageJson); }); if (gitInitialed) { firstCommit(); } welcome({ name: name, appPath: appPath, }); return [2 /*return*/]; } }); }); });