Commit f2bef82f authored by super-lin0's avatar super-lin0

cli init

parents
Pipeline #147 canceled with stages
/node_modules
/yarn.lock
/dist
package-lock.json
.DS_Store
Used in bin/cli.js to determine if it is in the local debug state.
**/*.svg
package.json
.umi
.umi-production
{
"singleQuote": true,
"trailingComma": "all",
"printWidth": 100,
"proseWrap": "never",
"overrides": [
{
"files": ".prettierrc",
"options": {
"parser": "json"
}
}
]
}
\ No newline at end of file
sudo: false
language: node_js
node_js:
- '8'
- '10'
install:
- npm install
script:
- npm run test
## The new CHNAGELOG will be updated on the [Release page](https://github.com/umijs/create-umi/releases).
0.9.5 / 2019-01-14
==================
* enhance: add tests files (#32)
0.9.4 / 2019-01-14
==================
* fix: create with typescript (#31)
* fix: 少了一个分号 (#30)
0.9.3 / 2019-01-13
==================
* yarn create umi时报错 (#29)
0.9.2 / 2019-01-12
==================
* fix: create-umi not found, Close #26, Close #27
* fix: create-umi -v
0.9.1 / 2019-01-12
==================
* enable treeShaking by default
0.9.0 / 2019-01-12
==================
* refact: improve create-umi (#25)
* 重构一遍,结构清晰一些
* app 支持 TypeScript,Close #22, Close #17
* app 添加 ESLint 校验、treeShaking 配置
* 优化 ant-design-pro 仓库 clone 时间问题,Close #20
* 优化选择界面的提示文案,Close #24
0.8.1 / 2019-01-05
==================
* fix: update umi-plugin-library to ^1.0.1-0
# create-umi
Creates a UmiJS application/plugin/block/library using the command line.
[![NPM version](https://img.shields.io/npm/v/create-umi.svg?style=flat)](https://npmjs.org/package/create-umi)
[![Build Status](https://img.shields.io/travis/umijs/create-umi.svg?style=flat)](https://travis-ci.org/umijs/create-umi)
[![NPM downloads](http://img.shields.io/npm/dm/create-umi.svg?style=flat)](https://npmjs.org/package/create-umi)
## Usage
```bash
$ yarn create umi [appName]
```
## Boilerplates
* `ant-design-pro` - Create project with a layout-only ant-design-pro boilerplate, use together with umi block.
* `app ` - Create project with a simple boilerplate, support typescript.
* `block ` - Create a umi block.
* `library ` - Create a library with umi.
* `plugin ` - Create a umi plugin.
## Usage Example
```bash
$ yarn create umi
? Select the boilerplate type (Use arrow keys)
ant-design-pro - Create project with a layout-only ant-design-pro boilerplate, use together with umi block.
❯ app - Create project with a simple boilerplate, support typescript.
block - Create a umi block.
library - Create a library with umi.
plugin - Create a umi plugin.
? Do you want to use typescript? (y/N)
? What functionality do you want to enable? (Press <space> to select, <a> to toggle all, <i> to invert selection)
❯◯ antd
◯ dva
◯ code splitting
◯ dll
create abc/package.json
create abc/.gitignore
create abc/.editorconfig
create abc/.env
create abc/.eslintrc
create abc/.prettierignore
create abc/.prettierrc
create abc/.umirc.js
create abc/mock/.gitkeep
create abc/src/assets/yay.jpg
create abc/src/global.css
create abc/src/layouts/index.css
create abc/src/layouts/index.tsx
create abc/src/pages/index.css
create abc/src/pages/index.tsx
create abc/tsconfig.json
create abc/typings.d.ts
📋 Copied to clipboard, just use Ctrl+V
✨ File Generate Done
```
## FAQ
### `yarn create umi` command failed
这个问题基本上都是因为没有添加 yarn global module 的路径到 PATH 环境变量引起的。
先执行 `yarn global bin` 拿到路径,然后添加到 PATH 环境变量里。
```bash
$ yarn global bin
/usr/local/bin
```
你也可以尝试用 npm,
```bash
$ npm create umi
```
或者手动安装 create-umi,并执行他,
```bash
$ npm install create-umi -g
$ create-umi
```
## Questions & Suggestions
Please open an issue [here](https://github.com/umijs/umi/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc).
## LICENSE
MIT
#!/usr/bin/env node
const yParser = require('yargs-parser');
const semver = require('semver');
const { existsSync } = require('fs');
const { join } = require('path');
const chalk = require('chalk');
const run = require('./lib/run');
// print version and @local
const args = yParser(process.argv.slice(2));
if (args.v || args.version) {
console.log(require('./package').version);
if (existsSync(join(__dirname, '.local'))) {
console.log(chalk.cyan('@local'));
}
process.exit(0);
}
if (!semver.satisfies(process.version, '>= 8.0.0')) {
console.error(chalk.red('✘ The generator will only work with Node v8.0.0 and up!'));
process.exit(1);
}
const name = args._[0] || '';
const { type } = args;
delete args.type;
run({
name,
type,
args,
});
const run = require('./lib/run');
module.exports.run = run;
const Generator = require('yeoman-generator');
const glob = require('glob');
const { statSync } = require('fs');
const { basename } = require('path');
const debug = require('debug')('create-umi:BasicGenerator');
function noop() {
return true;
}
class BasicGenerator extends Generator {
constructor(opts) {
super(opts);
this.opts = opts;
this.name = basename(opts.env.cwd);
}
isTsFile(f) {
return f.endsWith('.ts') || f.endsWith('.tsx') || !!/(tsconfig\.json|tslint\.yml)/g.test(f);
}
writeFiles({ context, filterFiles = noop }) {
debug(`context: ${JSON.stringify(context)}`);
glob
.sync('**/*', {
cwd: this.templatePath(),
dot: true,
})
.filter(filterFiles)
.forEach(file => {
debug(`copy ${file}`);
const filePath = this.templatePath(file);
if (statSync(filePath).isFile()) {
this.fs.copyTpl(
this.templatePath(filePath),
this.destinationPath(file.replace(/^_/, '.')),
context,
);
}
});
}
prompt(questions) {
process.send && process.send({ type: 'prompt' });
process.emit('message', { type: 'prompt' });
return super.prompt(questions);
}
}
module.exports = BasicGenerator;
{
"plugins": [
[
"@babel/plugin-transform-typescript",
{
"isTSX": true
}
]
]
}
# Ant Design Pro
This project is initialized with [Ant Design Pro](https://pro.ant.design). Follow is the quick guide for how to use.
## Environment Prepare
Install `node_modules`:
```bash
npm install
```
or
```bash
yarn
```
## Provided Scripts
Ant Design Pro provides some useful script to help you quick start and build with web project, code style check and test.
Scripts provided in `package.json`. It's safe to modify or add additional script:
### Start project
```bash
npm start
```
### Build project
```bash
npm run build
```
### Check code style
```bash
npm run lint
```
You can also use script to auto fix some lint error:
```bash
npm run lint:fix
```
### Test code
```bash
npm test
```
## More
You can view full document on our [official website](https://pro.ant.design). And welcome any feedback in our [github](https://github.com/ant-design/ant-design-pro).
const filterPkg = (pkgObject, ignoreList) => {
const devObj = {};
Object.keys(pkgObject).forEach(key => {
const isIgnore = ignoreList.some(reg => {
return new RegExp(reg).test(key);
});
if (isIgnore) {
return;
}
devObj[key] = pkgObject[key];
});
return devObj;
};
module.exports = filterPkg;
const fs = require("fs-extra");
const path = require("path");
const chalk = require("chalk");
const glob = require("glob");
const exec = require("execa");
const BasicGenerator = require("../../BasicGenerator");
const filterPkg = require("./filterPkg");
const prettier = require("prettier");
const sylvanas = require("sylvanas");
const sortPackage = require("sort-package-json");
const { getFastGithub } = require("umi-utils");
function log(...args) {
console.log(`${chalk.gray(">")}`, ...args);
}
function globList(patternList, options) {
let fileList = [];
patternList.forEach(pattern => {
fileList = [...fileList, ...glob.sync(pattern, options)];
});
return fileList;
}
const getGithubUrl = async () => {
const fastGithub = await getFastGithub();
if (fastGithub === "github.com.cnpmjs.org") {
return "https://github.com.cnpmjs.org/ant-design/ant-design-pro";
}
return "https://github.com/ant-design/ant-design-pro";
};
const PRO_PATH =
process.env.INIT_CWD || process.env.npm_rootpath || process.cwd();
class AntDesignProGenerator extends BasicGenerator {
prompting() {
if (this.opts.args.language) {
this.prompts = {
language: this.opts.args.language
};
} else {
const prompts = [
{
name: "language",
type: "list",
message: "Which language do you want to use?",
choices: ["TypeScript", "JavaScript"]
}
];
return this.prompt(prompts).then(props => {
this.prompts = props;
});
}
}
async writing() {
const { language } = this.prompts;
const isTypeScript = language === "TypeScript";
const projectName = this.opts.name || this.opts.env.cwd;
console.log(`this.opts::::${JSON.stringify(this.opts)}`);
const projectPath = path.resolve(projectName);
const envOptions = {
cwd: projectPath
};
const githubUrl = await getGithubUrl();
const gitArgs = [`clone`, githubUrl, `--depth=1`];
// Set branch if provided
if (this.opts.args.branch) {
gitArgs.push("--branch", this.opts.args.branch);
}
gitArgs.push(projectName);
// Clone remote branch
log(`git ${gitArgs.join(" ")}`);
await exec(`git`, gitArgs);
const packageJsonPath = path.resolve(projectPath, "package.json");
const pkg = require(packageJsonPath);
// Handle js version
if (!isTypeScript) {
log("[Sylvanas] Prepare js environment...");
const tsFiles = globList(["**/*.tsx", "**/*.ts"], {
...envOptions,
ignore: ["**/*.d.ts"]
});
sylvanas(tsFiles, {
...envOptions,
action: "overwrite"
});
log("[JS] Clean up...");
const removeTsFiles = globList(
["tsconfig.json", "**/*.d.ts"],
envOptions
);
removeTsFiles.forEach(filePath => {
const targetPath = path.resolve(projectPath, filePath);
fs.removeSync(targetPath);
});
}
// copy readme
const babelConfig = path.resolve(__dirname, "README.md");
fs.copySync(babelConfig, path.resolve(projectPath, "README.md"));
// gen package.json
if (pkg["create-nemean"]) {
const { ignoreScript = [], ignoreDependencies = [] } = pkg[
"create-nemean"
];
// filter scripts and devDependencies
const projectPkg = {
...pkg,
version: "1.0.0",
scripts: filterPkg(pkg.scripts, ignoreScript),
devDependencies: filterPkg(pkg.devDependencies, ignoreDependencies)
};
// remove create-nemean config
delete projectPkg["create-nemean"];
fs.writeFileSync(
path.resolve(projectPath, "package.json"),
// 删除一个包之后 json会多了一些空行。sortPackage 可以删除掉并且排序
// prettier 会容忍一个空行
prettier.format(JSON.stringify(sortPackage(projectPkg)), {
parser: "json"
})
);
}
// Clean up useless files
if (pkg["create-nemean"] && pkg["create-nemean"].ignore) {
log("Clean up...");
const ignoreFiles = pkg["create-nemean"].ignore;
const fileList = globList(ignoreFiles, envOptions);
fileList.forEach(filePath => {
const targetPath = path.resolve(projectPath, filePath);
fs.removeSync(targetPath);
});
}
}
}
module.exports = AntDesignProGenerator;
{
"description": "Create project with a layout-only ant-design-pro boilerplate, use together with umi block."
}
const debug = require('debug')('create-umi:generator');
const BasicGenerator = require('../../BasicGenerator');
class Generator extends BasicGenerator {
prompting() {
if (this.opts.args && 'isTypeScript' in this.opts.args && 'reactFeatures' in this.opts.args) {
this.prompts = {
isTypeScript: this.opts.args.isTypeScript,
reactFeatures: this.opts.args.reactFeatures,
};
} else {
const prompts = [
{
name: 'isTypeScript',
type: 'confirm',
message: 'Do you want to use typescript?',
default: false,
},
{
name: 'reactFeatures',
message: 'What functionality do you want to enable?',
type: 'checkbox',
choices: [
{name: 'antd', value: 'antd'},
{name: 'dva', value: 'dva'},
{name: 'code splitting', value: 'dynamicImport'},
{name: 'dll', value: 'dll'},
{name: 'internationalization', value: 'locale'},
],
},
];
return this.prompt(prompts).then(props => {
this.prompts = props;
});
}
}
writing() {
this.writeFiles({
context: {
name: this.name,
...this.prompts,
},
filterFiles: f => {
const { isTypeScript, reactFeatures } = this.prompts;
if (isTypeScript) {
if (f.endsWith('.js')) return false;
if (!reactFeatures.includes('dva')) {
if (f.startsWith('src/models') || f === 'src/app.ts') return false;
}
if (!reactFeatures.includes('locale')) {
if (f.startsWith('src/locales') || f.includes('umi-plugin-locale')) return false;
}
} else {
if (this.isTsFile(f)) return false;
if (!reactFeatures.includes('dva')) {
if (f.startsWith('src/models') || f === 'src/app.js') return false;
}
if (!reactFeatures.includes('locale')) {
if (f.startsWith('src/locales') || f.includes('umi-plugin-locale')) return false;
}
}
return true;
},
});
}
}
module.exports = Generator;
{
"description": "Create project with a simple boilerplate, support typescript."
}
\ No newline at end of file
# http://editorconfig.org
root = true
[*]
indent_style = space
indent_size = 2
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
[*.md]
trim_trailing_whitespace = false
[Makefile]
indent_style = tab
{
"extends": "eslint-config-umi"
}
**/*.md
**/*.svg
**/*.ejs
**/*.html
package.json
.umi
.umi-production
{
"singleQuote": true,
"trailingComma": "all",
"printWidth": 100,
"overrides": [
{
"files": ".prettierrc",
"options": { "parser": "json" }
}
]
}
// ref: https://umijs.org/config/
export default {
treeShaking: true,
routes: [
{
path: '/',
component: '../layouts/index',
routes: [
{ path: '/', component: '../pages/index' }
]
}
],
plugins: [
// ref: https://umijs.org/plugin/umi-plugin-react.html
['umi-plugin-react', {
antd: <% if (reactFeatures.includes('antd')) { %>true<% } else { %>false<% } %>,
dva: <% if (reactFeatures.includes('dva')) { %>true<% } else { %>false<% } %>,
dynamicImport: <% if (reactFeatures.includes('dynamicImport')) { %>{ webpackChunkName: true }<% } else { %>false<% } %>,
title: '<%= name %>',
dll: <% if (reactFeatures.includes('dll')) { %>true<% } else { %>false<% } %>,
<% if (reactFeatures.includes('locale')) { %>locale: {
enable: true,
default: 'en-US',
},<% } %>
routes: {
exclude: [<% if (reactFeatures.includes('dva')) { %>
/models\//,
/services\//,
/model\.(t|j)sx?$/,
/service\.(t|j)sx?$/,<% } %>
/components\//,
],
},
}],
],
}
import { IConfig } from 'umi-types';
// ref: https://umijs.org/config/
const config: IConfig = {
treeShaking: true,
routes: [
{
path: '/',
component: '../layouts/index',
routes: [
{ path: '/', component: '../pages/index' }
]
}
],
plugins: [
// ref: https://umijs.org/plugin/umi-plugin-react.html
['umi-plugin-react', {
antd: <% if (reactFeatures.includes('antd')) { %>true<% } else { %>false<% } %>,
dva: <% if (reactFeatures.includes('dva')) { %>true<% } else { %>false<% } %>,
dynamicImport: <% if (reactFeatures.includes('dynamicImport')) { %>{ webpackChunkName: true }<% } else { %>false<% } %>,
title: '<%= name %>',
dll: <% if (reactFeatures.includes('dll')) { %>true<% } else { %>false<% } %>,
<% if (reactFeatures.includes('locale')) { %>locale: {
enable: true,
default: 'en-US',
},<% } %>
routes: {
exclude: [<% if (reactFeatures.includes('dva')) { %>
/models\//,
/services\//,
/model\.(t|j)sx?$/,
/service\.(t|j)sx?$/,<% } %>
/components\//,
],
},
}],
],
}
export default config;
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# dependencies
/node_modules
/npm-debug.log*
/yarn-error.log
/yarn.lock
/package-lock.json
# production
/dist
# misc
.DS_Store
# umi
.umi
.umi-production
{
"private": true,
"scripts": {
"start": "umi dev",
"build": "umi build",
"test": "umi test",
<% if (!isTypeScript) { -%>
"lint": "eslint --ext .js src mock tests",
<% } -%>
<% if (isTypeScript) { -%>
"lint:es": "eslint --ext .js src mock tests",
"lint:ts": "tslint \"src/**/*.ts\" \"src/**/*.tsx\"",
<% } -%>
"precommit": "lint-staged"
},
"dependencies": {
<% if (reactFeatures.includes('dva')) { -%>
"dva": "^2.6.0-beta.6",
<% } -%>
<% if (reactFeatures.includes('antd')) { -%>
"antd": "^3.19.5",
<% } -%>
"react": "^16.8.6",
"react-dom": "^16.8.6"
},
"devDependencies": {
<% if (isTypeScript) { -%>
"@types/jest": "^23.3.12",
"@types/react": "^16.7.18",
"@types/react-dom": "^16.0.11",
"@types/react-test-renderer": "^16.0.3",
<% } -%>
"babel-eslint": "^9.0.0",
"eslint": "^5.4.0",
"eslint-config-umi": "^1.4.0",
"eslint-plugin-flowtype": "^2.50.0",
"eslint-plugin-import": "^2.14.0",
"eslint-plugin-jsx-a11y": "^5.1.1",
"eslint-plugin-react": "^7.11.1",
"husky": "^0.14.3",
"lint-staged": "^7.2.2",
"react-test-renderer": "^16.7.0",
<% if (isTypeScript) { -%>
"tslint": "^5.12.0",
"tslint-eslint-rules": "^5.4.0",
"tslint-react": "^3.6.0",
"umi": "^2.9.0",
"umi-plugin-react": "^1.8.0",
"umi-types": "^0.3.0"
<% } else { -%>
"umi": "^2.7.7",
"umi-plugin-react": "^1.8.4"
<% } -%>
},
"lint-staged": {
<% if (isTypeScript) { -%>
"*.{ts,tsx}": ["tslint --fix", "git add"],
<% } -%>
"*.{js,jsx}": ["eslint --fix", "git add"]
},
"engines": {
"node": ">=8.0.0"
}
}
export const dva = {
config: {
onError(err) {
err.preventDefault();
console.error(err.message);
},
},
};
export const dva = {
config: {
onError(err: ErrorEvent) {
err.preventDefault();
console.error(err.message);
},
},
};
html, body, #root {
height: 100%;
}
body {
margin: 0;
}
import BasicLayout from '..';
import renderer from 'react-test-renderer';
describe('Layout: BasicLayout', () => {
it('Render correctly', () => {
const wrapper = renderer.create(<BasicLayout />);
expect(wrapper.root.children.length).toBe(1);
const outerLayer = wrapper.root.children[0];
expect(outerLayer.type).toBe('div');
const title = outerLayer.children[0];
expect(title.type).toBe('h1');
expect(title.children[0]).toBe('Yay! Welcome to umi!');
});
});
import 'jest';
import BasicLayout from '..';
import React from 'react';
import renderer, { ReactTestInstance, ReactTestRenderer } from 'react-test-renderer';
describe('Layout: BasicLayout', () => {
it('Render correctly', () => {
const wrapper: ReactTestRenderer = renderer.create(<BasicLayout />);
expect(wrapper.root.children.length).toBe(1);
const outerLayer = wrapper.root.children[0] as ReactTestInstance;
expect(outerLayer.type).toBe('div');
const title = outerLayer.children[0] as ReactTestInstance;
expect(title.type).toBe('h1');
expect(title.children[0]).toBe('Yay! Welcome to umi!');
});
});
.normal {
font-family: Georgia, sans-serif;
text-align: center;
}
.title {
font-size: 2.5rem;
font-weight: normal;
letter-spacing: -1px;
background: darkslateblue;
padding: .6em 0;
color: white;
margin: 0;
}
import styles from './index.css';
function BasicLayout(props) {
return (
<div className={styles.normal}>
<h1 className={styles.title}>Yay! Welcome to umi!</h1>
{props.children}
</div>
);
}
export default BasicLayout;
import React from 'react';
import styles from './index.css';
const BasicLayout: React.FC = props => {
return (
<div className={styles.normal}>
<h1 className={styles.title}>Yay! Welcome to umi!</h1>
{props.children}
</div>
);
};
export default BasicLayout;
export default {
'index.start': 'Getting Started',
}
export default {
'index.start': 'Getting Started',
}
export const formatMessage = (): string => 'Mock text';
import Index from '..';
import renderer from 'react-test-renderer';
<% if (reactFeatures.includes('locale')) { %>jest.mock('umi-plugin-locale');
<% } %>
describe('Page: index', () => {
it('Render correctly', () => {
const wrapper = renderer.create(<Index />);
expect(wrapper.root.children.length).toBe(1);
const outerLayer = wrapper.root.children[0];
expect(outerLayer.type).toBe('div');
expect(outerLayer.children.length).toBe(2);
<% if (reactFeatures.includes('locale')) { %>const getStartLink = outerLayer.findAllByProps({
href: 'https://umijs.org/guide/getting-started.html',
});
expect(getStartLink.length).toBe(1);
expect(getStartLink[0].children).toMatchObject(['Mock text']);<% } %>
});
});
import 'jest';
import Index from '..';
import React from 'react';
import renderer, { ReactTestInstance, ReactTestRenderer } from 'react-test-renderer';
<% if (reactFeatures.includes('locale')) { %>jest.mock('umi-plugin-locale');
<% } %>
describe('Page: index', () => {
it('Render correctly', () => {
const wrapper: ReactTestRenderer = renderer.create(<Index />);
expect(wrapper.root.children.length).toBe(1);
const outerLayer = wrapper.root.children[0] as ReactTestInstance;
expect(outerLayer.type).toBe('div');
expect(outerLayer.children.length).toBe(2);
<% if (reactFeatures.includes('locale')) { %>const getStartLink = outerLayer.findAllByProps({
href: 'https://umijs.org/guide/getting-started.html',
}) as ReactTestInstance[];
expect(getStartLink.length).toBe(1);
expect(getStartLink[0].children).toMatchObject(['Mock text']);<% } %>
});
});
.normal {
font-family: Georgia, sans-serif;
margin-top: 4em;
text-align: center;
}
.welcome {
height: 328px;
background: url(../assets/yay.jpg) no-repeat center 0;
background-size: 388px 328px;
}
.list {
font-size: 1.2em;
margin-top: 1.8em;
list-style: none;
line-height: 1.5em;
}
.list code {
background: #f7f7f7;
}
import styles from './index.css';
<% if (reactFeatures.includes('locale')) { %>import { formatMessage } from 'umi-plugin-locale';<% } -%>
export default function() {
return (
<div className={styles.normal}>
<div className={styles.welcome} />
<ul className={styles.list}>
<li>To get started, edit <code>src/pages/index.js</code> and save to reload.</li>
<li>
<a href="https://umijs.org/guide/getting-started.html">
<% if (reactFeatures.includes('locale')) { %>{formatMessage({ id: 'index.start' })}<% } else { %>Getting Started<% } %>
</a>
</li>
</ul>
</div>
);
}
import React from 'react';
import styles from './index.css';
<% if (reactFeatures.includes('locale')) { %>import { formatMessage } from 'umi-plugin-locale';<% } -%>
export default function() {
return (
<div className={styles.normal}>
<div className={styles.welcome} />
<ul className={styles.list}>
<li>To get started, edit <code>src/pages/index.js</code> and save to reload.</li>
<li>
<a href="https://umijs.org/guide/getting-started.html">
<% if (reactFeatures.includes('locale')) { %>{formatMessage({ id: 'index.start' })}<% } else { %>Getting Started<% } %>
</a>
</li>
</ul>
</div>
);
}
{
"compilerOptions": {
"target": "esnext",
"module": "esnext",
"moduleResolution": "node",
"importHelpers": true,
"jsx": "react",
"esModuleInterop": true,
"sourceMap": true,
"baseUrl": ".",
"strict": true,
"paths": {
"@/*": ["src/*"]
},
"allowSyntheticDefaultImports": true
}
}
defaultSeverity: error
extends:
- tslint-react
- tslint-eslint-rules
rules:
eofline: true
no-console: true
no-construct: true
no-debugger: true
no-reference: true
declare module '*.css';
declare module "*.png";
/**
* 不是真实的 webpack 配置,仅为兼容 webstorm 和 intellij idea 代码跳转
* ref: https://github.com/umijs/umi/issues/1109#issuecomment-423380125
*/
module.exports = {
resolve: {
alias: {
'@': require('path').resolve(__dirname, 'src'),
},
},
};
const BasicGenerator = require('../../BasicGenerator');
class Generator extends BasicGenerator {
prompting() {
const prompts = [
{
name: 'name',
message: `What's the block name?`,
default: this.name,
},
{
name: 'description',
message: `What's your block description?`,
},
{
name: 'mail',
message: `What's your email?`,
},
{
name: 'author',
message: `What's your name?`,
},
{
name: 'repo',
message: `Which repo is your block stored under github?`,
default: 'umijs/umi-blocks',
},
{
name: 'isTypeScript',
type: 'confirm',
message: 'Do you want to use typescript?',
default: false,
},
];
return this.prompt(prompts).then(props => {
this.prompts = props;
});
}
writing() {
this.writeFiles({
context: this.prompts,
filterFiles: f => {
const { isTypeScript } = this.prompts;
if (isTypeScript) {
if (f.endsWith('.js')) return false;
} else {
if (this.isTsFile(f)) return false;
}
return true;
},
});
}
}
module.exports = Generator;
{
"description": "Create a umi block."
}
**/*.md
**/*.svg
**/*.ejs
**/*.html
package.json
.umi
.umi-production
{
"singleQuote": true,
"trailingComma": "all",
"printWidth": 100,
"overrides": [
{
"files": ".prettierrc",
"options": { "parser": "json" }
}
]
}
export default {
plugins: [
['umi-plugin-block-dev', {}],
],
}
import { IConfig } from 'umi-types';
const config: IConfig = {
plugins: [
['umi-plugin-block-dev', {}],
],
}
export default config;
The MIT License (MIT)
Copyright (c) 2019-present <%= author %> (<%= mail %>)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
# @umi-material/<%= name %>
<%= description %>
## Usage
```sh
umi block https://github.com/<%= repo %>/tree/master/<%= name %>
```
## LICENSE
MIT
/yarn.lock
/package-lock.json
/dist
/node_modules
/pages
.umi
.umi-production
{
"name": "@umi-block/<%= name %>",
"version": "0.0.1",
"description": "<%= description %>",
"main": "src/index.js",
"authors": {
"name": "<%= author %>",
"email": "<%= mail %>"
},
"repository": "<%= repo %>/<%= name %>",
"scripts": {
"dev": "umi dev"
},
"dependencies": {
"react": ">=16.0.0"
},
"devDependencies": {
"umi": "^2.9.0",
<% if (isTypeScript) { -%>
"umi-plugin-block-dev": "^2.0.0",
"umi-types": "^0.3.0"
<% } else { -%>
"umi-plugin-block-dev": "^2.0.0"
<% } -%>
},
"license": "MIT"
}
.normal {
background: #79F2AA;
}
import styles from './index.css';
export default function() {
return (
<div className={styles.normal}>
<h1>I am a umi block!</h1>
</div>
);
}
import React from 'react';
import styles from './index.css';
const Block: React.FC = () => {
return (
<div className={styles.normal}>
<h1>I am a umi block!</h1>
</div>
);
}
export default Block;
{
"compilerOptions": {
"target": "esnext",
"module": "esnext",
"moduleResolution": "node",
"importHelpers": true,
"jsx": "react",
"esModuleInterop": true,
"sourceMap": true,
"baseUrl": ".",
"strict": true,
"paths": {
"@/*": ["src/*"]
},
"allowSyntheticDefaultImports": true
}
}
declare module '*.css';
declare module "*.png";
const BasicGenerator = require('../../BasicGenerator');
class Generator extends BasicGenerator {
prompting() {
const prompts = [
{
name: 'name',
message: `What's the library name?`,
default: this.name,
},
{
name: 'description',
message: `What's your library description?`,
},
{
name: 'mail',
message: `What's your email?`,
},
{
name: 'author',
message: `What's your name?`,
},
{
name: 'repo',
message: `Which repo is your library stored under github?`,
},
{
name: 'isTypeScript',
type: 'confirm',
message: 'Do you want to use typescript?',
default: false,
},
];
return this.prompt(prompts).then(props => {
this.prompts = props;
});
}
writing() {
this.writeFiles({
context: this.prompts,
filterFiles: f => {
const { isTypeScript } = this.prompts;
if (isTypeScript) {
if (f.endsWith('.js')) return false;
} else {
if (this.isTsFile(f)) return false;
}
return true;
},
});
}
}
module.exports = Generator;
{
"description": "Create a library with umi."
}
export default {
cjs: 'rollup',
esm: 'rollup',
}
import { IBundleOptions } from 'father';
const options: IBundleOptions = {
cjs: 'rollup',
esm: 'rollup',
doc: { typescript: true },
};
export default options;
**/*.md
**/*.mdx
package.json
.umi
.umi-production
{
"singleQuote": true,
"trailingComma": "all",
"printWidth": 100,
"overrides": [
{
"files": ".prettierrc",
"options": { "parser": "json" }
}
]
}
The MIT License (MIT)
Copyright (c) 2019-present <%= author %> (<%= mail %>)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
# @umi-material/<%= name %>
<%= description %>
## Usage
```sh
umi block https://github.com/<%= repo %>/tree/master/<%= name %>
```
## LICENSE
MIT
/yarn.lock
/package-lock.json
/dist
/.docz
/node_modules
{
"name": "<%= name %>",
"version": "0.0.1",
"description": "<%= description %>",
"main": "dist/index.js",
"module": "dist/index.esm.js",
"authors": {
"name": "<%= author %>",
"email": "<%= mail %>"
},
"repository": "<%= repo %>/<%= name %>",
"scripts": {
"dev": "father doc dev",
"build": "father build"
},
"peerDependencies": {
"react": "16.x"
},
"devDependencies": {
<% if (isTypeScript) { -%>
"father": "^2.16.0",
"typescript": "^3.3.3"
<% } else { -%>
"father": "^2.16.0"
<% } -%>
},
"license": "MIT"
}
import React from 'react';
import styles from './index.css';
export default function(props) {
return (
<button
className={styles.button}
style={{
fontSize: props.size === 'large' ? 40 : 20,
}}
>
{ props.children }
</button>
);
}
---
name: Home
route: /
order: -1
sidebar: true
---
import Button from './';
# Button Component
## Normal Button
<Button>Hi</Button>
## Large Button
<Button size="large">Hi</Button>
import React from 'react';
import styles from './index.css';
export interface ButtonProps {
size?: 'large' | 'default';
}
const Button: React.FC<ButtonProps> = function(props) {
return (
<button
className={styles.button}
style={{
fontSize: props.size === 'large' ? 40 : 20,
}}
>
{props.children}
</button>
);
};
export default Button;
{
"compilerOptions": {
"target": "esnext",
"module": "esnext",
"moduleResolution": "node",
"importHelpers": true,
"jsx": "react",
"esModuleInterop": true,
"sourceMap": true,
"baseUrl": ".",
"strict": true,
"paths": {
"@/*": ["src/*"]
},
"allowSyntheticDefaultImports": true
}
}
declare module '*.css';
declare module "*.png";
const BasicGenerator = require('../../BasicGenerator');
class Generator extends BasicGenerator {
prompting() {
const prompts = [
{
name: 'name',
message: `What's the plugin name?`,
default: this.name,
},
{
name: 'description',
message: `What's your plugin used for?`,
},
{
name: 'mail',
message: `What's your email?`,
},
{
name: 'author',
message: `What's your name?`,
},
{
name: 'org',
message: `Which organization is your plugin stored under github?`,
},
{
name: 'isTypeScript',
type: 'confirm',
message: 'Do you want to use typescript?',
default: false,
},
{
name: 'withUmiUI',
type: 'confirm',
message: 'Does your plugin have ui interaction(umi ui)?',
default: false,
},
];
return this.prompt(prompts).then(props => {
this.prompts = props;
});
}
// lang: ts || js
isUIFiles(file, lang) {
const uiFile = lang === 'ts'
? 'ui/index.tsx'
: 'ui/index.js';
return file === uiFile;
}
writing() {
this.writeFiles({
context: this.prompts,
filterFiles: f => {
const { isTypeScript, withUmiUI } = this.prompts;
if (isTypeScript) {
if (f.endsWith('.js')) return false;
// filter ui files
if (!withUmiUI && this.isUIFiles(f, 'ts')) return false;
} else {
if (this.isTsFile(f)) return false;
// filter ui files
if (!withUmiUI && this.isUIFiles(f)) return false;
}
return true;
},
});
}
}
module.exports = Generator;
{
"description": "Create a umi plugin."
}
\ No newline at end of file
export default [
{
cjs: 'babel',
},
<% if (withUmiUI) { -%>
{
entry: 'ui/index.js',
umd: {
name: '<%= name %>',
minFile: false,
},
},
<% } -%>
];
export default [
{
cjs: 'babel',
},
<% if (withUmiUI) { -%>
{
entry: 'ui/index.tsx',
typescriptOpts: {
check: false,
},
umd: {
name: '<%= name %>',
minFile: false,
},
},
<% } -%>
];
The MIT License (MIT)
Copyright (c) 2018-present <%= author %> (<%= mail %>)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
# umi-plugin-<%= name %>
[![NPM version](https://img.shields.io/npm/v/umi-plugin-<%= name %>.svg?style=flat)](https://npmjs.org/package/umi-plugin-<%= name %>)
[![NPM downloads](http://img.shields.io/npm/dm/umi-plugin-<%= name %>.svg?style=flat)](https://npmjs.org/package/umi-plugin-<%= name %>)
<%= description %>
## Install
```bash
# or yarn
$ npm install
```
## Development UI
UI start:
```bash
$ npm run build --watch
$ npm run start
```
<img src="https://user-images.githubusercontent.com/13595509/67025108-10925980-f138-11e9-8f46-899eef3e098b.png" width="768" />
UI mini start:
```bash
$ npm run build --watch
$ npm run start:mini
```
<img src="https://user-images.githubusercontent.com/13595509/67024897-bbeede80-f137-11e9-9f19-6a3f0ea3f6cd.png" width="768" />
## Usage
Configure in `.umirc.js`,
```js
export default {
plugins: [
['umi-plugin-<%= name %>', options],
],
}
```
## Options
TODO
## LICENSE
MIT
/node_modules
/yarn.lock
/package-lock.json
/example/dist
/example/node_modules
/example/pages/.umi
/example/pages/.umi-production
/lib
<% if (withUmiUI) { -%>
/dist
<% } -%>
import { join } from 'path';
export default {
routes: [
{ path: '/', component: './index' },
],
plugins: [
join(__dirname, '..', require('../package').main || 'index.js'),
],
}
import { join } from 'path';
import { IConfig } from 'umi-types';
export default {
routes: [
{ path: '/', component: './index' },
],
plugins: [
join(__dirname, '..', require('../package').main || 'index.js'),
],
} as IConfig;
declare module '*.css';
declare module '*.less';
import React from 'react';
import styles from './index.css';
export default function() {
return (
<div className={styles.normal}>
<h1>Page index</h1>
</div>
);
}
import React from 'react';
import styles from './index.css';
export default function() {
return (
<div className={styles.normal}>
<h1>Page index</h1>
</div>
);
}
{
"name": "umi-plugin-<%= name %>",
"version": "0.0.1",
"description": "<%= description %>",
"authors": {
"name": "<%= author %>",
"email": "<%= mail %>"
},
"repository": "<%= org %>/<%= name %>",
"peerDependencies": {
<% if (withUmiUI) { -%>
"antd": "4.x",
"react": "^16.8.6",
"react-dom": "^16.8.6",
<% } -%>
"umi": "2.x || ^2.9.0-0"
},
"main": "lib/index.js",
"scripts": {
<% if (withUmiUI) { -%>
"start:mini": "cross-env UMI_UI=1 APP_ROOT=$PWD/example umi dev",
"start": "cross-env CURRENT_PROJECT=example umi ui",
<% } else { -%>
"start": "cross-env APP_ROOT=$PWD/example umi dev",
<% } -%>
"build": "father-build",
"prepublishOnly": "npm run build && np --no-cleanup --yolo --no-publish"
},
"devDependencies": {
"cross-env": "^6.0.3",
"father-build": "^1.8.0",
<% if (withUmiUI) { -%>
"antd": "^4.0.0-alpha.0",
<% } -%>
"np": "^5.0.3",
"umi": "^2.9.0",
"umi-types": "^0.4.0-beta.4"
},
"files": [
<% if (withUmiUI) { -%>
"dist",
<% } -%>
"lib",
"src",
"ui"
],
"license": "MIT"
}
// ref:
// - https://umijs.org/plugin/develop.html
export default function (api, options) {
// Example: output the webpack config
api.chainWebpackConfig(config => {
// console.log(config.toString());
});
<% if (withUmiUI) { -%>
api.addUIPlugin(require.resolve('../dist/index.umd'));
api.onUISocket(({ action, failure, success }) => {
if (action.type === 'org.<%= author %>.<%= name %>.test') {
success({
data: '<%= name %>.test',
});
}
});
<% } %>
}
// ref:
// - https://umijs.org/plugin/develop.html
import { IApi } from 'umi-types';
export default function (api: IApi, options) {
// Example: output the webpack config
api.chainWebpackConfig(config => {
// console.log(config.toString());
});
<% if (withUmiUI) { -%>
api.addUIPlugin(require.resolve('../dist/index.umd'));
api.onUISocket(({ action, failure, success }) => {
if (action.type === 'org.<%= author %>.<%= name %>.test') {
success({
data: '<%= name %>.test',
});
}
});
<% } %>
}
{
"compilerOptions": {
"module": "esnext",
"target": "esnext",
"lib": ["esnext", "dom"],
"sourceMap": true,
"baseUrl": ".",
"jsx": "react",
"allowSyntheticDefaultImports": true,
"moduleResolution": "node",
"forceConsistentCasingInFileNames": true,
"noImplicitReturns": true,
"suppressImplicitAnyIndexErrors": true,
"noUnusedLocals": true,
"experimentalDecorators": true,
"declaration": false
}
}
import { Button } from 'antd';
export default (api) => {
const { callRemote } = api;
function PluginPanel() {
return (
<div style={{ padding: 20 }}>
<Button
type="primary"
onClick={async () => {
const { data } = await callRemote({
type: 'org.<%= author %>.<%= name %>.test',
});
alert(data);
}}
>Test</Button>
</div>
);
}
api.addPanel({
title: '<%= name %>',
path: '/<%= name %>',
icon: 'home',
component: PluginPanel,
});
}
import { Button } from 'antd';
import { IUiApi } from 'umi-types'
export default (api: IUiApi) => {
const { callRemote } = api;
function PluginPanel() {
return (
<div style={{ padding: 20 }}>
<Button
type="primary"
onClick={async () => {
const { data } = await callRemote({
type: 'org.<%= author %>.<%= name %>.test',
});
alert(data);
}}
>Test</Button>
</div>
);
}
api.addPanel({
title: '<%= name %>',
path: '/<%= name %>',
icon: 'home',
component: PluginPanel,
});
}
const fs = require('fs');
const path = require('path');
const chalk = require('chalk');
const mkdirp = require('mkdirp');
const inquirer = require('inquirer');
const clipboardy = require('clipboardy');
const generators = fs
.readdirSync(`${__dirname}/generators`)
.filter(f => !f.startsWith('.'))
.map(f => {
return {
name: `${f.padEnd(15)} - ${chalk.gray(require(`./generators/${f}/meta.json`).description)}`,
value: f,
short: f,
};
});
const runGenerator = async (generatorPath, { name = '', cwd = process.cwd(), args = {} }) => {
return new Promise(resolve => {
if (name) {
mkdirp.sync(name);
cwd = path.join(cwd, name);
}
const Generator = require(generatorPath);
const generator = new Generator({
name,
env: {
cwd,
},
resolved: require.resolve(generatorPath),
args,
});
return generator.run(() => {
if (name) {
if (process.platform !== `linux` || process.env.DISPLAY) {
clipboardy.writeSync(`cd ${name}`);
console.log('📋 Copied to clipboard, just use Ctrl+V');
}
}
console.log('✨ File Generate Done');
resolve(true);
});
});
};
const run = async config => {
process.send && process.send({ type: 'prompt' });
process.emit('message', { type: 'prompt' });
let { type } = config;
if (!type) {
const answers = await inquirer.prompt([
{
name: 'type',
message: 'Select the boilerplate type',
type: 'list',
choices: generators,
},
]);
type = answers.type;
}
try {
return runGenerator(`./generators/${type}`, config);
} catch(e) {
console.error(chalk.red(`> Generate failed`), e);
process.exit(1);
}
};
module.exports = run;
{
"name": "create-nemean",
"version": "0.0.19",
"description": "Creates a UmiJS application using the command line.",
"homepage": "https://github.com/umijs/create-umi",
"bugs": {
"url": "https://github.com/umijs/create-umi/issues"
},
"repository": {
"type": "git",
"url": "https://github.com/umijs/create-umi"
},
"license": "MIT",
"files": [
"cli.js",
"index.js",
"lib"
],
"bin": {
"create-nemean": "cli.js"
},
"scripts": {
"test": "egg-bin test",
"prettier": "prettier -c --write '**/*'"
},
"dependencies": {
"chalk": "^2.4.2",
"clipboardy": "^2.1.0",
"debug": "^4.1.1",
"execa": "^1.0.0",
"fs-extra": "^8.0.1",
"glob": "^7.1.4",
"inquirer": "^6.4.1",
"mkdirp": "^0.5.1",
"prettier": "^1.17.0",
"semver": "^6.1.0",
"sort-package-json": "^1.22.1",
"sylvanas": "~0.2.0",
"umi-utils": "^1.5.2",
"yargs-parser": "^13.1.1",
"yeoman-generator": "^4.0.1"
},
"devDependencies": {
"coffee": "^5.2.1",
"egg-bin": "^4.13.0",
"mm": "^2.5.0",
"np": "^5.0.1"
},
"authors": [
"chencheng <sorrycc@gmail.com> (https://github.com/sorrycc)"
]
}
const mm = require('mm');
const getFastGithub = require('umi-utils/lib/getFastGithub');
mm(getFastGithub, 'default', () => {
return 'github.com.cnpmjs.org';
});
const mm = require('mm');
const getFastGithub = require('umi-utils/lib/getFastGithub');
mm(getFastGithub, 'default', () => {
return 'github.com';
});
const coffee = require('coffee');
const path = require('path');
const os = require('os');
const fs = require('fs');
const assert = require('assert');
describe('test umi-create', () => {
it('test generate antd pro project from github', async () => {
let temp = fs.mkdtempSync(path.join(os.tmpdir(), `umi-create`));
if (os.platform() === 'darwin') {
temp = path.join('/private', temp);
}
const Coffee = coffee.Coffee;
const fixtures = path.join(__dirname, 'fixtures');
const response = await new Coffee({
method: 'fork',
cmd: path.join(__dirname, '../cli.js'),
opt: { cwd: temp },
})
.beforeScript(path.join(fixtures, 'mock_github.js'))
.waitForPrompt()
.write('\n')
.waitForPrompt()
.writeKey('DOWN', 'ENTER')
.expect('code', 0)
.end();
const expectStdout = [
'? Select the boilerplate type (Use arrow keys)',
'❯ ant-design-pro - Create project with a layout-only ant-design-pro boilerplate',
', use together with umi block. ',
' app - Create project with a simple boilerplate, support typescript',
'. ',
' block - Create a umi block. ',
' library - Create a library with umi. ',
' plugin - Create a umi plugin. \u001b[41D\u001b[41C\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[G? Select the boilerplate type ant-design-pro\u001b[44D\u001b[44C',
'? Which language do you want to use? (Use arrow keys)',
'❯ TypeScript ',
' JavaScript \u001b[13D\u001b[13C\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[G? Which language do you want to use? ',
' TypeScript ',
'❯ JavaScript \u001b[13D\u001b[13C\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[G? Which language do you want to use? JavaScript\u001b[47D\u001b[47C',
`> git clone https://github.com/ant-design/ant-design-pro --depth=1 ${temp}`,
'> [Sylvanas] Prepare js environment...',
'> [JS] Clean up...',
'> Clean up...',
'✨ File Generate Done',
'',
];
assert.equal(response.stdout, expectStdout.join('\n'));
assert.equal(response.code, 0);
});
it('test generate antd pro project from github.com.cnpmjs.org', async () => {
let temp = fs.mkdtempSync(path.join(os.tmpdir(), `umi-create`));
if (os.platform() === 'darwin') {
temp = path.join('/private', temp);
}
const Coffee = coffee.Coffee;
const fixtures = path.join(__dirname, 'fixtures');
const response = await new Coffee({
method: 'fork',
cmd: path.join(__dirname, '../cli.js'),
opt: { cwd: temp },
})
.beforeScript(path.join(fixtures, 'mock_cnpmjs.js'))
.waitForPrompt()
.write('\n')
.waitForPrompt()
.write('\n')
.end();
const expectStdout = [
'? Select the boilerplate type (Use arrow keys)',
'❯ ant-design-pro - Create project with a layout-only ant-design-pro boilerplate',
', use together with umi block. ',
' app - Create project with a simple boilerplate, support typescript',
'. ',
' block - Create a umi block. ',
' library - Create a library with umi. ',
' plugin - Create a umi plugin. \u001b[41D\u001b[41C\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[G? Select the boilerplate type ant-design-pro\u001b[44D\u001b[44C',
'? Which language do you want to use? (Use arrow keys)',
'❯ TypeScript ',
' JavaScript \u001b[13D\u001b[13C\u001b[2K\u001b[1A\u001b[2K\u001b[1A\u001b[2K\u001b[G? Which language do you want to use? TypeScript\u001b[47D\u001b[47C',
`> git clone https://github.com.cnpmjs.org/ant-design/ant-design-pro --depth=1 ${temp}`,
'> Clean up...',
'✨ File Generate Done',
'',
];
assert.equal(response.stdout, expectStdout.join('\n'));
assert.equal(response.code, 0);
});
it('tsconfig.json should be removed if JavaScript is picked', async () => {
let temp = fs.mkdtempSync(path.join(os.tmpdir(), `umi-create`));
if (os.platform() === 'darwin') {
temp = path.join('/private', temp);
}
const Coffee = coffee.Coffee;
const fixtures = path.join(__dirname, 'fixtures');
const response = await new Coffee({
method: 'fork',
cmd: path.join(__dirname, '../cli.js'),
opt: { cwd: temp },
})
.beforeScript(path.join(fixtures, 'mock_cnpmjs.js'))
.waitForPrompt()
.write('\n')
.waitForPrompt()
.writeKey('DOWN', 'ENTER')
.end();
assert.equal(response.code, 0);
assert.ok(fs.existsSync(path.join(temp, 'jsconfig.json')));
assert.ok(!fs.existsSync(path.join(temp, 'tsconfig.json')));
});
});
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment