зеркало из https://github.com/microsoft/just.git
Plop - just-stack switched to using plop for codegen (#194)
* moving to plop * plopped it good * continue on the journey to plop * WIP: getting monorepo plopped up * monorepo test * uifabric works! * code gen subsequent packages * Change files * yarn.lock * changed behavior of the downloadPackage function
This commit is contained in:
Родитель
185663bd7a
Коммит
3f32788be4
|
@ -0,0 +1 @@
|
|||
**/plop-templates/**
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"type": "major",
|
||||
"comment": "Switches to using plop.js for codegen",
|
||||
"packageName": "create-just",
|
||||
"email": "kchau@microsoft.com",
|
||||
"commit": "2ea4e433c300ed8323aaab0fcf03f927ba8ab78b",
|
||||
"date": "2019-08-05T05:37:37.993Z"
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"type": "minor",
|
||||
"comment": "Getting rid of defunct just-stack / monorepo tasks",
|
||||
"packageName": "just-scripts",
|
||||
"email": "kchau@microsoft.com",
|
||||
"commit": "2ea4e433c300ed8323aaab0fcf03f927ba8ab78b",
|
||||
"date": "2019-08-05T05:38:12.241Z"
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"type": "patch",
|
||||
"comment": "Switches to using plop.js for codegen",
|
||||
"packageName": "just-scripts-utils",
|
||||
"email": "kchau@microsoft.com",
|
||||
"commit": "2ea4e433c300ed8323aaab0fcf03f927ba8ab78b",
|
||||
"date": "2019-08-05T05:37:52.360Z"
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"type": "minor",
|
||||
"comment": "Switched to Lerna",
|
||||
"packageName": "just-stack-monorepo",
|
||||
"email": "kchau@microsoft.com",
|
||||
"commit": "2ea4e433c300ed8323aaab0fcf03f927ba8ab78b",
|
||||
"date": "2019-08-05T05:38:24.049Z"
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"type": "minor",
|
||||
"comment": "code gen subsequent packages",
|
||||
"packageName": "just-stack-react",
|
||||
"email": "kchau@microsoft.com",
|
||||
"commit": "2ea4e433c300ed8323aaab0fcf03f927ba8ab78b",
|
||||
"date": "2019-08-05T05:38:31.984Z"
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"type": "minor",
|
||||
"comment": "Switches to using plop.js for codegen",
|
||||
"packageName": "just-stack-single-lib",
|
||||
"email": "kchau@microsoft.com",
|
||||
"commit": "2ea4e433c300ed8323aaab0fcf03f927ba8ab78b",
|
||||
"date": "2019-08-05T05:38:36.357Z"
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"type": "minor",
|
||||
"comment": "Switches to using plop.js for codegen",
|
||||
"packageName": "just-stack-uifabric",
|
||||
"email": "kchau@microsoft.com",
|
||||
"commit": "2ea4e433c300ed8323aaab0fcf03f927ba8ab78b",
|
||||
"date": "2019-08-05T05:38:39.894Z"
|
||||
}
|
|
@ -14,7 +14,7 @@
|
|||
"change": "beachball change",
|
||||
"checkchange": "beachball check",
|
||||
"publish:beachball": "beachball publish",
|
||||
"start": "node ./scripts/watch.js",
|
||||
"start": "lerna run start --parallel",
|
||||
"test": "lerna run test",
|
||||
"lint": "eslint packages --ext .ts,.js"
|
||||
},
|
||||
|
|
|
@ -12,22 +12,25 @@
|
|||
},
|
||||
"scripts": {
|
||||
"build": "npx webpack",
|
||||
"start": "npx webpack --watch --progress --display minimal --mode development"
|
||||
"start": "npx webpack --watch --progress --display minimal --mode development",
|
||||
"watch": "tsc -w --preserveWatchOutput"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
"devDependencies": {
|
||||
"@types/node": "^10.12.18",
|
||||
"@types/prompts": "^1.2.0",
|
||||
"@types/yargs": "12.0.1",
|
||||
"@types/yargs-parser": "^13.0.0",
|
||||
"@types/fs-extra": "^5.0.4",
|
||||
"typescript": "~3.4.4",
|
||||
"envinfo": "^7.3.1",
|
||||
"typescript": "~3.5.3",
|
||||
"fs-extra": "^7.0.1",
|
||||
"prompts": "^2.0.1",
|
||||
"yargs": "^12.0.5",
|
||||
"yargs-parser": "^13.1.1",
|
||||
"node-plop": "^0.19.0",
|
||||
"webpack": "~4.29.5",
|
||||
"webpack-cli": "^3.2.1",
|
||||
"ts-loader": "^5.3.3",
|
||||
"ts-loader": "^6.0.4",
|
||||
"just-scripts-utils": ">=0.8.2 <1.0.0"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
export function convertToBypass(gen: any, args: any) {
|
||||
const prompts = gen.prompts;
|
||||
|
||||
const bypassArgs = args._;
|
||||
|
||||
prompts.forEach((prompt: any, index: number) => {
|
||||
if (prompt.name && args[prompt.name] !== undefined) {
|
||||
bypassArgs[index] = args[prompt.name];
|
||||
}
|
||||
});
|
||||
|
||||
return bypassArgs;
|
||||
}
|
|
@ -1,11 +1,11 @@
|
|||
import { paths, logger, applyTemplate, prettyPrintMarkdown, rushUpdate, downloadPackage } from 'just-scripts-utils';
|
||||
import { paths, logger, prettyPrintMarkdown, downloadPackage } from 'just-scripts-utils';
|
||||
import path from 'path';
|
||||
import { readdirSync } from 'fs';
|
||||
import fse from 'fs-extra';
|
||||
import { readdirSync, readFileSync, existsSync } from 'fs';
|
||||
import prompts from 'prompts';
|
||||
import { execSync, spawnSync } from 'child_process';
|
||||
import { execSync } from 'child_process';
|
||||
import yargs from 'yargs';
|
||||
import os from 'os';
|
||||
import { getPlopGenerator, runGenerator } from '../plop';
|
||||
import * as pkg from '../packageManager';
|
||||
|
||||
const initCwd = process.cwd();
|
||||
|
||||
|
@ -13,19 +13,32 @@ function checkEmptyRepo(projectPath: string) {
|
|||
return readdirSync(projectPath).length === 0;
|
||||
}
|
||||
|
||||
async function getTemplatePath(pathName: string, registry?: string) {
|
||||
function getStackName(stackPath: string) {
|
||||
const packageJson = JSON.parse(readFileSync(path.join(stackPath, 'package.json'), 'utf-8'));
|
||||
return packageJson.name;
|
||||
}
|
||||
|
||||
async function getStackPath(pathName: string, registry?: string) {
|
||||
if (pathName.match(/^\./)) {
|
||||
// relative to initCwd
|
||||
return path.join(initCwd, pathName, 'template');
|
||||
} else if (pathName.match(/\//)) {
|
||||
return path.join(initCwd, pathName);
|
||||
} else if (pathName.match(/^\//)) {
|
||||
// absolute path
|
||||
return path.join(pathName, 'template');
|
||||
return pathName;
|
||||
}
|
||||
|
||||
// download it from feed
|
||||
return await downloadPackage(pathName, undefined, registry);
|
||||
}
|
||||
|
||||
/**
|
||||
* Init involves these steps:
|
||||
* 1. pick stack
|
||||
* 2. pick name
|
||||
* 3. plop!
|
||||
* 4. git init and commit
|
||||
* 5. yarn install
|
||||
*/
|
||||
export async function initCommand(argv: yargs.Arguments) {
|
||||
// TODO: autosuggest just-stack-* packages from npmjs.org
|
||||
if (!argv.stack) {
|
||||
|
@ -34,9 +47,10 @@ export async function initCommand(argv: yargs.Arguments) {
|
|||
name: 'stack',
|
||||
message: 'What type of repo to create?',
|
||||
choices: [
|
||||
{ title: 'Monorepo', value: 'just-stack-monorepo' },
|
||||
{ title: 'UI Fabric React Application', value: 'just-stack-uifabric' },
|
||||
{ title: 'Basic library', value: 'just-stack-single-lib' }
|
||||
{ title: 'React App', value: 'just-stack-react' },
|
||||
{ title: 'UI Fabric (React)', value: 'just-stack-uifabric' },
|
||||
{ title: 'Basic TypeScript', value: 'just-stack-single-lib' },
|
||||
{ title: 'Monorepo', value: 'just-stack-monorepo' }
|
||||
]
|
||||
});
|
||||
argv.stack = stack;
|
||||
|
@ -48,7 +62,7 @@ export async function initCommand(argv: yargs.Arguments) {
|
|||
type: 'text',
|
||||
name: 'name',
|
||||
message: 'What is the name of the repo to create?',
|
||||
validate: (name) => !name ? false : true
|
||||
validate: name => (!name ? false : true)
|
||||
});
|
||||
name = response.name;
|
||||
paths.projectPath = path.join(paths.projectPath, name);
|
||||
|
@ -59,50 +73,77 @@ export async function initCommand(argv: yargs.Arguments) {
|
|||
paths.projectPath = path.join(paths.projectPath, name);
|
||||
}
|
||||
|
||||
if (!fse.pathExistsSync(paths.projectPath)) {
|
||||
fse.mkdirpSync(paths.projectPath);
|
||||
}
|
||||
argv.name = name;
|
||||
|
||||
process.chdir(paths.projectPath);
|
||||
const stackPath = await getStackPath(argv.stack, argv.registry);
|
||||
const stackName = getStackName(stackPath!);
|
||||
const generator = getPlopGenerator(stackPath!, paths.projectPath, stackName);
|
||||
|
||||
logger.info(`Code Generation Information:
|
||||
|
||||
project path: ${paths.projectPath}
|
||||
stack: ${stackName}
|
||||
|
||||
`);
|
||||
|
||||
await runGenerator(generator, argv);
|
||||
|
||||
logger.info(`Initializing the repo in ${paths.projectPath}`);
|
||||
|
||||
const templatePath = await getTemplatePath(argv.stack, argv.registry);
|
||||
pkg.install(argv.registry, paths.projectPath);
|
||||
|
||||
if (templatePath) {
|
||||
applyTemplate(templatePath, paths.projectPath, { name });
|
||||
|
||||
if (argv.stack.includes('monorepo')) {
|
||||
rushUpdate(paths.projectPath);
|
||||
} else {
|
||||
const npmCmd = path.join(path.dirname(process.execPath), os.platform() === 'win32' ? 'npm.cmd' : 'npm');
|
||||
spawnSync(npmCmd, ['install', ...(argv.registry ? ['--registry', argv.registry] : [])], { stdio: 'inherit' });
|
||||
}
|
||||
|
||||
try {
|
||||
execSync('git init');
|
||||
execSync('git add .');
|
||||
execSync('git commit -m "initial commit"');
|
||||
} catch (e) {
|
||||
logger.warn('Looks like you may not have git installed or there was some sort of error initializing the git repo');
|
||||
logger.info(`
|
||||
try {
|
||||
execSync('git init', { cwd: paths.projectPath });
|
||||
execSync('git add .', { cwd: paths.projectPath });
|
||||
execSync('git commit -m "initial commit"', { cwd: paths.projectPath });
|
||||
} catch (e) {
|
||||
logger.warn('Looks like you may not have git installed or there was some sort of error initializing the git repo');
|
||||
logger.info(`
|
||||
Please make sure you have git installed and then issue the following:
|
||||
|
||||
cd ${paths.projectPath}
|
||||
git init
|
||||
git add .
|
||||
git commit -m "initial commit"
|
||||
cd ${paths.projectPath}
|
||||
git init
|
||||
git add .
|
||||
git commit -m "initial commit"
|
||||
|
||||
`);
|
||||
}
|
||||
|
||||
logger.info('All Set!');
|
||||
|
||||
const readmeFile = path.join(paths.projectPath, 'README.md');
|
||||
if (fse.existsSync(readmeFile)) {
|
||||
logger.info('\n' + prettyPrintMarkdown(fse.readFileSync(readmeFile).toString()));
|
||||
}
|
||||
} else {
|
||||
logger.error('Having trouble downloading and extracting the template package');
|
||||
}
|
||||
|
||||
logger.info('All Set!');
|
||||
|
||||
showNextSteps(argv, stackName);
|
||||
}
|
||||
|
||||
function showNextSteps(argv: any, stackName: string) {
|
||||
logger.info(
|
||||
prettyPrintMarkdown(`
|
||||
You have successfully created a new repo based on the '${argv.stack}' template!
|
||||
|
||||
## Keeping Up-to-date
|
||||
You can keep your build tools up-to-date by updating these two devDependencies:
|
||||
|
||||
* ${stackName}
|
||||
* just-scripts
|
||||
|
||||
## Next Steps
|
||||
|
||||
To start developing code, you can start the innerloop dev server:
|
||||
|
||||
cd ${paths.projectPath}
|
||||
${pkg.getYarn() ? 'yarn' : 'npm'} start
|
||||
|
||||
You can build your project in production mode with these commands:
|
||||
|
||||
cd ${paths.projectPath}
|
||||
${pkg.getYarn() ? 'yarn' : 'npm run'} build
|
||||
|
||||
${existsSync(path.join(paths.projectPath, 'plopfile.js')) &&
|
||||
`
|
||||
This repository contains code generators that can be triggered by:
|
||||
|
||||
cd ${paths.projectPath}
|
||||
${pkg.getYarn() ? 'yarn' : 'npm run'} gen
|
||||
|
||||
`}`)
|
||||
);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
import envinfo from 'envinfo';
|
||||
import os from 'os';
|
||||
|
||||
let envInfoCache: { Binaries: { Yarn: any; npm: any } };
|
||||
|
||||
export const getEnvInfo = () => {
|
||||
return envInfoCache;
|
||||
};
|
||||
|
||||
export const initialize = async () => {
|
||||
envInfoCache = JSON.parse(
|
||||
await envinfo.run(
|
||||
{
|
||||
Binaries: ['Yarn', 'npm']
|
||||
},
|
||||
{ json: true, showNotFound: true }
|
||||
)
|
||||
);
|
||||
|
||||
envInfoCache.Binaries.Yarn.path = envInfoCache.Binaries.Yarn && expandHome(envInfoCache.Binaries.Yarn.path);
|
||||
envInfoCache.Binaries.npm.path = envInfoCache.Binaries.npm && expandHome(envInfoCache.Binaries.npm.path);
|
||||
|
||||
return envInfoCache;
|
||||
};
|
||||
|
||||
function expandHome(path: string) {
|
||||
if (path.startsWith('~/')) {
|
||||
return path.replace('~/', os.homedir() + '/');
|
||||
}
|
||||
|
||||
return path;
|
||||
}
|
|
@ -1,7 +1,25 @@
|
|||
import yargs from 'yargs';
|
||||
import parser from 'yargs-parser';
|
||||
import { initCommand } from './commands/initCommand';
|
||||
import { initialize } from './getEnvInfo';
|
||||
|
||||
yargs
|
||||
const args = parser(process.argv.slice(2), {
|
||||
alias: {
|
||||
name: ['n'],
|
||||
stack: ['s'],
|
||||
registry: ['r']
|
||||
}
|
||||
});
|
||||
|
||||
if (args._.length > 0) {
|
||||
args.name = args._[0];
|
||||
}
|
||||
|
||||
(async () => {
|
||||
await initialize();
|
||||
initCommand(args);
|
||||
})();
|
||||
|
||||
/*yargs
|
||||
.command({
|
||||
aliases: '*',
|
||||
command: 'init [name]',
|
||||
|
@ -13,3 +31,4 @@ yargs
|
|||
handler: initCommand
|
||||
})
|
||||
.help().argv;
|
||||
*/
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
import { spawnSync } from 'child_process';
|
||||
import { getEnvInfo } from './getEnvInfo';
|
||||
|
||||
export function getYarn() {
|
||||
const yarnInfo = getEnvInfo().Binaries.Yarn;
|
||||
return yarnInfo && yarnInfo.path;
|
||||
}
|
||||
|
||||
function getNpm() {
|
||||
const npmInfo = getEnvInfo().Binaries.npm;
|
||||
return npmInfo && npmInfo.path;
|
||||
}
|
||||
|
||||
export function install(registry: string, cwd: string) {
|
||||
const registryArgs = registry ? ['--registry', registry] : [];
|
||||
|
||||
if (getYarn()) {
|
||||
return spawnSync(getYarn(), ['install', ...registryArgs], { stdio: 'inherit', cwd });
|
||||
} else {
|
||||
return spawnSync(getNpm(), ['install', ...registryArgs], { stdio: 'inherit', cwd });
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
import nodePlop from 'node-plop';
|
||||
import path from 'path';
|
||||
import { logger } from 'just-task-logger';
|
||||
|
||||
export function getPlopGenerator(plopfilePath: string, destBasePath: string, stackName: string) {
|
||||
const plopfile = path.join(plopfilePath, 'plopfile.js');
|
||||
const plop = nodePlop(plopfile, { destBasePath, force: false });
|
||||
let generator = plop.getGenerator(`repo:${stackName}`) as any;
|
||||
if (!generator) {
|
||||
generator = plop.getGenerator('repo') as any;
|
||||
}
|
||||
|
||||
return generator;
|
||||
}
|
||||
|
||||
export async function runGenerator(generator: any, args: any) {
|
||||
const results = await generator.runActions(args, {
|
||||
onComment: (comment: string) => {
|
||||
logger.info(comment);
|
||||
}
|
||||
});
|
||||
|
||||
if (results.failures && results.failures.length > 0) {
|
||||
throw new Error('Error: ' + results.failures[0].error);
|
||||
}
|
||||
|
||||
// do something after the actions have run
|
||||
for (let change of results.changes) {
|
||||
if (change.path) {
|
||||
logger.info(change.path);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,7 +1,8 @@
|
|||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "lib"
|
||||
"outDir": "lib",
|
||||
"noImplicitAny": false
|
||||
},
|
||||
"include": ["src/index.ts"]
|
||||
}
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
declare module 'envinfo' {
|
||||
var x: any;
|
||||
export = x;
|
||||
}
|
|
@ -23,5 +23,6 @@ module.exports = {
|
|||
node: {
|
||||
__dirname: false
|
||||
},
|
||||
devtool: 'none',
|
||||
stats: 'errors-only'
|
||||
};
|
||||
|
|
|
@ -66,10 +66,10 @@ describe('downloadPackage', () => {
|
|||
expect(_isDevMode('foo')).toBe(false);
|
||||
});
|
||||
|
||||
it('returns local template path in dev mode', async () => {
|
||||
it('returns local path in dev mode', async () => {
|
||||
const pkg = 'just-stack-monorepo';
|
||||
const result = await downloadPackage(pkg);
|
||||
expect(result).toBe(path.join(__dirname, '../../..', pkg, 'template'));
|
||||
expect(result).toBe(path.join(__dirname, '../../..', pkg));
|
||||
});
|
||||
|
||||
it('removes previous download and handles npm pack errors', async () => {
|
||||
|
@ -120,6 +120,6 @@ describe('downloadPackage', () => {
|
|||
});
|
||||
|
||||
const result = await downloadPackage(pkg, version);
|
||||
expect(result).toBe(path.join(fakeTemp, pkg, 'package/template'));
|
||||
expect(result).toBe(path.join(fakeTemp, pkg, 'package'));
|
||||
});
|
||||
});
|
||||
|
|
|
@ -37,7 +37,7 @@ export function _isDevMode(pkg: string): boolean {
|
|||
*/
|
||||
export async function downloadPackage(pkg: string, version: string = 'latest', registry: string | null = null): Promise<string | null> {
|
||||
if (_isDevMode(pkg) && version === 'latest') {
|
||||
return path.join(dirname || __dirname, '../../', pkg, 'template');
|
||||
return path.join(dirname || __dirname, '../../', pkg);
|
||||
}
|
||||
|
||||
const npmCmd = os.platform() === 'win32' ? 'npm.cmd' : 'npm';
|
||||
|
@ -67,7 +67,7 @@ export async function downloadPackage(pkg: string, version: string = 'latest', r
|
|||
file: path.join(pkgPath, pkgFile),
|
||||
cwd: pkgPath
|
||||
});
|
||||
return path.join(pkgPath, 'package', 'template');
|
||||
return path.join(pkgPath, 'package');
|
||||
} else {
|
||||
logger.error(`Could not find downloaded tgz file ${pkgPath}`);
|
||||
return null;
|
||||
|
|
|
@ -1,3 +1,2 @@
|
|||
export * from './lib';
|
||||
export * from './monorepo';
|
||||
export * from './webapp';
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { task, series, parallel } from 'just-task';
|
||||
import { cleanTask, tscTask, jestTask, upgradeStackTask, defaultCleanPaths } from '../tasks';
|
||||
import { cleanTask, tscTask, jestTask, defaultCleanPaths, tslintTask } from '../tasks';
|
||||
|
||||
export function lib() {
|
||||
task('clean', cleanTask([...defaultCleanPaths(), 'lib-commonjs']));
|
||||
|
@ -12,13 +12,14 @@ export function lib() {
|
|||
task('jest', jestTask());
|
||||
task('jest:watch', jestTask({ watch: true }));
|
||||
|
||||
task('build', series('clean', 'ts', 'jest'));
|
||||
task('tslint', tslintTask());
|
||||
|
||||
task('build', series('ts'));
|
||||
task('test', series('jest'));
|
||||
task('lint', series('tslint'));
|
||||
|
||||
task('test', series('clean', 'jest'));
|
||||
task('start', series('clean', 'ts:watch'));
|
||||
task('start-test', series('clean', 'jest:watch'));
|
||||
task('start-test', series('jest:watch'));
|
||||
|
||||
task('rebuild', series('clean', 'build'));
|
||||
|
||||
task('upgrade-stack', upgradeStackTask());
|
||||
}
|
||||
|
|
|
@ -1,11 +0,0 @@
|
|||
import { task, option } from 'just-task';
|
||||
import { addPackageTask, upgradeRepoTask } from '../tasks';
|
||||
|
||||
export function monorepo() {
|
||||
option('cwd');
|
||||
option('name', { alias: 'n' });
|
||||
option('stack', { alias: 's' });
|
||||
option('latest');
|
||||
task('add-package', 'adds a package to the monorepo', addPackageTask);
|
||||
task('upgrade-repo', 'upgrades packages inside the monorepo according to the just-stack template', upgradeRepoTask);
|
||||
}
|
|
@ -1,27 +1,26 @@
|
|||
import { task, series, parallel } from 'just-task';
|
||||
import { cleanTask, tscTask, jestTask, webpackTask, webpackDevServerTask, upgradeStackTask, defaultCleanPaths } from '../tasks';
|
||||
import { cleanTask, tscTask, jestTask, webpackTask, webpackDevServerTask, defaultCleanPaths, tslintTask } from '../tasks';
|
||||
|
||||
export function webapp() {
|
||||
task('clean', cleanTask([...defaultCleanPaths(), 'lib-commonjs']));
|
||||
|
||||
task('ts:commonjs', tscTask({ module: 'commonjs', outDir: 'lib-commonjs' }));
|
||||
task('ts:esm', tscTask({ module: 'esnext', outDir: 'lib' }));
|
||||
task('ts:watch', tscTask({ module: 'esnext', outDir: 'lib', watch: true }));
|
||||
task('ts', parallel('ts:commonjs', 'ts:esm'));
|
||||
task('ts', parallel('ts:esm'));
|
||||
|
||||
task('jest', jestTask());
|
||||
task('jest:watch', jestTask({ watch: true }));
|
||||
|
||||
task('tslint', tslintTask());
|
||||
|
||||
task('webpack', webpackTask());
|
||||
|
||||
task('webpack:watch', webpackDevServerTask());
|
||||
|
||||
task('build', series('clean', 'ts', parallel('jest', 'webpack')));
|
||||
task('test', series('clean', 'jest'));
|
||||
task('start', series('clean', 'webpack:watch'));
|
||||
task('start-test', series('clean', 'jest:watch'));
|
||||
task('build', series('ts', 'webpack'));
|
||||
task('test', series('jest'));
|
||||
task('start', series('webpack:watch'));
|
||||
task('start-test', series('jest:watch'));
|
||||
|
||||
task('rebuild', series('clean', 'build'));
|
||||
|
||||
task('upgrade-stack', upgradeStackTask());
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
export const displayBailoutOverlay = {
|
||||
export const displayBailoutOverlay = () => ({
|
||||
stats: {
|
||||
// Examine all modules
|
||||
maxModules: Infinity,
|
||||
// Display bailout reasons
|
||||
optimizationBailout: true
|
||||
}
|
||||
};
|
||||
});
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
export const fileOverlay = {
|
||||
export const fileOverlay = () => ({
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
|
@ -7,4 +7,7 @@ export const fileOverlay = {
|
|||
}
|
||||
]
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
// @deprecated - we used to give default options only, now we use functions as a convention
|
||||
fileOverlay.module = fileOverlay().module;
|
||||
|
|
|
@ -2,6 +2,6 @@ import { tryRequire } from '../../tryRequire';
|
|||
|
||||
const HtmlWebpackPlugin = tryRequire('html-webpack-plugin');
|
||||
|
||||
export const htmlOverlay = {
|
||||
plugins: [...(HtmlWebpackPlugin ? [new HtmlWebpackPlugin()] : [])]
|
||||
};
|
||||
export const htmlOverlay = (options: any) => ({
|
||||
plugins: [...(HtmlWebpackPlugin ? [new HtmlWebpackPlugin(options)] : [])]
|
||||
});
|
||||
|
|
|
@ -107,6 +107,7 @@ export const createStylesOverlay = function(options: CssLoaderOptions = {}) {
|
|||
};
|
||||
};
|
||||
|
||||
export const stylesOverlay = createStylesOverlay({
|
||||
localIdentName: defaultIdentName
|
||||
});
|
||||
export const stylesOverlay = () =>
|
||||
createStylesOverlay({
|
||||
localIdentName: defaultIdentName
|
||||
});
|
||||
|
|
|
@ -2,7 +2,7 @@ import { tryRequire } from '../../tryRequire';
|
|||
|
||||
const ForkTsCheckerPlugin = tryRequire('fork-ts-checker-webpack-plugin');
|
||||
|
||||
export const tsOverlay = {
|
||||
export const tsOverlay = () => ({
|
||||
resolve: {
|
||||
extensions: ['.wasm', '.mjs', '.js', '.ts', '.tsx', '.json']
|
||||
},
|
||||
|
@ -21,4 +21,4 @@ export const tsOverlay = {
|
|||
]
|
||||
},
|
||||
plugins: [...(ForkTsCheckerPlugin ? [new ForkTsCheckerPlugin()] : [])]
|
||||
};
|
||||
});
|
||||
|
|
|
@ -14,4 +14,4 @@ export const basicWebpackConfig: any = {
|
|||
}
|
||||
};
|
||||
|
||||
export const webpackConfig: any = merge(basicWebpackConfig, stylesOverlay, tsOverlay, fileOverlay, displayBailoutOverlay);
|
||||
export const webpackConfig: any = merge(basicWebpackConfig, stylesOverlay(), tsOverlay(), fileOverlay(), displayBailoutOverlay());
|
||||
|
|
|
@ -14,4 +14,4 @@ export const basicWebpackServeConfig: any = {
|
|||
}
|
||||
};
|
||||
|
||||
export const webpackServeConfig: any = merge(basicWebpackServeConfig, stylesOverlay, tsOverlay, fileOverlay);
|
||||
export const webpackServeConfig: any = merge(basicWebpackServeConfig, stylesOverlay(), tsOverlay(), fileOverlay());
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
CHANGELOG.*
|
||||
*.log
|
||||
package-deps.json
|
||||
template.spec.js
|
||||
jest.config.js
|
||||
ndoe_modules
|
|
@ -1 +0,0 @@
|
|||
module.exports = require('../../scripts/jest.template.config');
|
|
@ -12,17 +12,5 @@
|
|||
"just-stack"
|
||||
],
|
||||
"author": "",
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
"build": "npm test",
|
||||
"test": "jest"
|
||||
},
|
||||
"devDependencies": {
|
||||
"fs-extra": "^7.0.1",
|
||||
"glob": "^7.1.3",
|
||||
"jest": "^24.0.0",
|
||||
"jest-expect-message": "^1.0.2",
|
||||
"json5": "^2.1.0",
|
||||
"just-scripts-utils": "0.8.2"
|
||||
}
|
||||
"license": "MIT"
|
||||
}
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
module.exports = {
|
||||
presets: ['@babel/preset-env', '@babel/preset-typescript', '@babel/preset-react']
|
||||
};
|
|
@ -0,0 +1,4 @@
|
|||
node_modules
|
||||
lib
|
||||
lib-commonjs
|
||||
dist
|
|
@ -0,0 +1,5 @@
|
|||
module.exports = {
|
||||
clearMocks: true,
|
||||
testEnvironment: 'jsdom',
|
||||
testMatch: ['<rootDir>/src/**/__tests__/**/*.[jt]s?(x)', '<rootDir>/src/**/?(*.)+(spec|test).[tj]s?(x)']
|
||||
};
|
|
@ -1,3 +1,3 @@
|
|||
// @ts-check
|
||||
const { taskPresets } = require('just-scripts');
|
||||
|
||||
taskPresets.webapp();
|
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"name": "{{name}}",
|
||||
"version": "0.1.0",
|
||||
"license": "MIT",
|
||||
"main": "lib-commonjs/index.js",
|
||||
"module": "lib/index.js",
|
||||
"scripts": {
|
||||
"build": "just-scripts build",
|
||||
"just": "just-scripts",
|
||||
"start": "just-scripts start",
|
||||
"test": "just-scripts test",
|
||||
"change": "npx beachball change",
|
||||
"gen": "npx plop"
|
||||
},
|
||||
"dependencies": {
|
||||
"react": "^16.8.6",
|
||||
"react-dom": "^16.8.6"
|
||||
},
|
||||
"devDependencies": {
|
||||
"just-stack-react": "^0.2.0",
|
||||
"{{repoName}}-scripts": "^0.26.0"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
import React from 'react';
|
||||
|
||||
export interface \{{pascalCase componentName}}Props {
|
||||
// Fill in props here
|
||||
}
|
||||
|
||||
export const \{{pascalCase componentName}} = (props: \{{pascalCase componentName}}Props) => {
|
||||
return (
|
||||
<div>
|
||||
{/* TODO */}
|
||||
</div>
|
||||
);
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
module.exports = plop => {
|
||||
plop.setGenerator('component', {
|
||||
prompts: [
|
||||
{
|
||||
type: 'input',
|
||||
name: 'componentName',
|
||||
message: 'Name of the component (will be converted to PascalCase): '
|
||||
}
|
||||
],
|
||||
|
||||
actions: [
|
||||
{
|
||||
type: 'add',
|
||||
templateFile: 'plop-templates/component/component.tsx.hbs',
|
||||
path: 'src/components/{{pascalCase componentName}}.tsx'
|
||||
}
|
||||
]
|
||||
});
|
||||
};
|
|
@ -0,0 +1,9 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"/>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,3 @@
|
|||
import React from 'react';
|
||||
|
||||
export default () => <div>This is an application</div>;
|
|
@ -0,0 +1,7 @@
|
|||
import { hello } from '../helloworld';
|
||||
describe('hello', () => {
|
||||
it('says hello', () => {
|
||||
const result = hello('world');
|
||||
expect(result).toBe('hello world');
|
||||
});
|
||||
});
|
|
@ -0,0 +1,3 @@
|
|||
export const hello = (name: string) => {
|
||||
return `hello ${name}`;
|
||||
};
|
|
@ -0,0 +1,5 @@
|
|||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import App from './App';
|
||||
|
||||
ReactDOM.render(<App />, document.getElementById('app'));
|
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"target": "esnext",
|
||||
"module": "commonjs",
|
||||
"jsx": "react",
|
||||
"declaration": true,
|
||||
"outDir": "./lib",
|
||||
"strict": true,
|
||||
"moduleResolution": "node",
|
||||
"esModuleInterop": true,
|
||||
"typeRoots": ["node_modules/@types", "node_modules/just-stack-react/node_modules/@types"]
|
||||
},
|
||||
|
||||
"include": ["src", "typings/*.d.ts"]
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
const { webpackConfig, webpackMerge, htmlOverlay } = require('just-scripts');
|
||||
|
||||
module.exports = webpackMerge(
|
||||
webpackConfig,
|
||||
htmlOverlay({
|
||||
template: 'public/index.html'
|
||||
}),
|
||||
{
|
||||
// Here you can custom webpack configurations
|
||||
}
|
||||
);
|
|
@ -0,0 +1,13 @@
|
|||
const { webpackMerge, htmlOverlay, webpackServeConfig } = require('just-scripts');
|
||||
module.exports = webpackMerge(
|
||||
webpackServeConfig,
|
||||
htmlOverlay({
|
||||
template: 'public/index.html'
|
||||
}),
|
||||
{
|
||||
// Here you can custom webpack configurations
|
||||
output: {
|
||||
publicPath: '/'
|
||||
}
|
||||
}
|
||||
);
|
|
@ -0,0 +1,4 @@
|
|||
node_modules
|
||||
lib
|
||||
lib-commonjs
|
||||
dist
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"packages": ["packages/*", "scripts"],
|
||||
"useWorkspaces": true,
|
||||
"npmClient": "yarn",
|
||||
"version": "0.0.0"
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
"name": "{{name}}",
|
||||
"private": true,
|
||||
"version": "1.0.0",
|
||||
"main": "index.js",
|
||||
"license": "MIT",
|
||||
"workspaces": ["packages/*", "scripts"],
|
||||
"devDependencies": {
|
||||
"just-stack-monorepo": "^0.6.2",
|
||||
"lerna": "^3.13.2",
|
||||
"beachball": "^1.11.5",
|
||||
"plop": "^2.4.0"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "lerna run build --stream",
|
||||
"test": "lerna run test --stream",
|
||||
"change": "beachball change",
|
||||
"gen": "plop"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
module.exports = function(plop) {
|
||||
plop.load('just-stack-monorepo/plopfile.repo.js');
|
||||
};
|
|
@ -0,0 +1,2 @@
|
|||
#!/usr/bin/env node
|
||||
require('just-scripts/bin/just-scripts');
|
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
"name": "{{name}}-scripts",
|
||||
"private": true,
|
||||
"version": "0.0.1",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"author": "",
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"{{name}}-scripts": "just-scripts.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"just-scripts": "^0.26.0"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
module.exports = function(plop) {
|
||||
plop.setGenerator('repo:just-stack-monorepo', {
|
||||
actions: [
|
||||
{
|
||||
type: 'addMany',
|
||||
templateFiles: ['plop-templates/**/*.*', 'plop-templates/**/.*'],
|
||||
base: 'plop-templates/repo',
|
||||
destination: '.',
|
||||
force: true
|
||||
}
|
||||
]
|
||||
});
|
||||
};
|
|
@ -0,0 +1,27 @@
|
|||
const fs = require('fs');
|
||||
|
||||
module.exports = function(plop) {
|
||||
const packageJson = JSON.parse(fs.readFileSync(require.resolve('package.json', { paths: [process.cwd()] })));
|
||||
|
||||
plop.setGenerator('react-package', {
|
||||
description: `Generates a React package`,
|
||||
prompts: [
|
||||
{
|
||||
type: 'input',
|
||||
name: 'name',
|
||||
message: 'Enter a name for the package: '
|
||||
}
|
||||
],
|
||||
actions: [
|
||||
{
|
||||
type: 'addMany',
|
||||
templateFiles: ['plop-templates/react-package/**/*', 'plop-templates/react-package/**/.*'],
|
||||
destination: 'packages/{{name}}',
|
||||
base: 'plop-templates/react-package',
|
||||
data: {
|
||||
repoName: packageJson.name
|
||||
}
|
||||
}
|
||||
]
|
||||
});
|
||||
};
|
|
@ -1,36 +0,0 @@
|
|||
const path = require('path');
|
||||
const fse = require('fs-extra');
|
||||
const glob = require('glob');
|
||||
const json = require('json5');
|
||||
const { applyTemplate } = require('just-scripts-utils');
|
||||
|
||||
describe('stack snapshot', () => {
|
||||
const snapshotPath = path.resolve(__dirname, 'temp');
|
||||
const templatePath = path.resolve(__dirname, 'template');
|
||||
let jsonFiles;
|
||||
|
||||
afterAll(() => {
|
||||
fse.removeSync(snapshotPath);
|
||||
});
|
||||
|
||||
beforeAll(() => {
|
||||
applyTemplate(templatePath, snapshotPath, { name: 'testproject' });
|
||||
jsonFiles = glob.sync('**/*.json', { cwd: snapshotPath });
|
||||
});
|
||||
|
||||
it('has legal json files', () => {
|
||||
jsonFiles.forEach(jsonFile => {
|
||||
if (jsonFile.includes('rush')) {
|
||||
expect(
|
||||
() => json.parse(fse.readFileSync(path.resolve(snapshotPath, jsonFile)).toString()),
|
||||
`${jsonFile} cannot be parsed as JSON (with comments).`
|
||||
).not.toThrow();
|
||||
} else {
|
||||
expect(
|
||||
() => JSON.parse(fse.readFileSync(path.resolve(snapshotPath, jsonFile)).toString()),
|
||||
`${jsonFile} cannot be parsed as JSON.`
|
||||
).not.toThrow();
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
|
@ -1,31 +0,0 @@
|
|||
# Logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
|
||||
.DS_Store
|
||||
|
||||
node_modules
|
||||
lib
|
||||
lib-commonjs
|
||||
lib-esm
|
||||
lib-es2015
|
||||
build
|
||||
coverage
|
||||
dist
|
||||
temp
|
||||
|
||||
*.scss.ts
|
||||
|
||||
documentation/lib/core/metadata.js
|
||||
documentation/lib/core/MetadataBlog.js
|
||||
|
||||
documentation/website/translated_docs
|
||||
documentation/website/build/
|
||||
documentation/website/yarn.lock
|
||||
documentation/website/i18n/*
|
||||
|
||||
# Rush files
|
||||
common/temp/**
|
||||
package-deps.json
|
|
@ -1,26 +0,0 @@
|
|||
{
|
||||
// When enabled, will trim trailing whitespace when you save a file.
|
||||
"files.trimTrailingWhitespace": true,
|
||||
// Controls whether the editor should render whitespace characters
|
||||
"editor.renderWhitespace": "all",
|
||||
"files.exclude": {
|
||||
"**/.git": true,
|
||||
"**/.DS_Store": true,
|
||||
"**/coverage": true,
|
||||
"**/*.scss.ts": true
|
||||
},
|
||||
// Configure glob patterns for excluding files and folders in searches. Inherits all glob patterns from the file.exclude setting.
|
||||
"search.exclude": {
|
||||
"common/temp": true,
|
||||
"**/node_modules": true,
|
||||
"**/lib": true,
|
||||
"**/lib-commonjs": true,
|
||||
"**/lib-esm": true,
|
||||
"**/lib-es2015": true,
|
||||
"**/dist": true
|
||||
},
|
||||
"files.associations": {
|
||||
"rush.json": "jsonc",
|
||||
"**/common/config/rush/*.json": "jsonc"
|
||||
}
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
# {{name}}
|
||||
|
||||
{{name}} is a monorepo created and managed with the `create-just` utility.
|
||||
|
||||
## Next Steps
|
||||
|
||||
Now that you have created this repository, run the following to get started:
|
||||
|
||||
```sh
|
||||
npm install
|
||||
npm run add-package
|
||||
```
|
|
@ -1,177 +0,0 @@
|
|||
/**
|
||||
* This configuration file defines custom commands for the "rush" command-line.
|
||||
* For full documentation, please see https://rushjs.io
|
||||
*/
|
||||
{
|
||||
"$schema": "https://developer.microsoft.com/json-schemas/rush/v5/command-line.schema.json",
|
||||
|
||||
/**
|
||||
* Custom "commands" introduce new verbs for the command-line. To see the help for these
|
||||
* example commands, try "rush --help", "rush my-bulk-command --help", or
|
||||
* "rush my-global-command --help".
|
||||
*/
|
||||
"commands": [
|
||||
// {
|
||||
// /**
|
||||
// * (Required) Determines the type of custom command.
|
||||
// * Rush's "bulk" commands are invoked separately for each project. Rush will look in
|
||||
// * each project's package.json file for a "scripts" entry whose name matches the
|
||||
// * command name. By default, the command will run for every project in the repo,
|
||||
// * according to the dependency graph (similar to how "rush build" works).
|
||||
// * The set of projects can be restricted e.g. using the "--to" or "--from" parameters.
|
||||
// */
|
||||
// "commandKind": "bulk",
|
||||
|
||||
// /**
|
||||
// * (Required) The name that will be typed as part of the command line. This is also the name
|
||||
// * of the "scripts" hook in the project's package.json file.
|
||||
// * The name should be comprised of lower case words separated by hyphens.
|
||||
// */
|
||||
// "name": "my-bulk-command",
|
||||
|
||||
// /**
|
||||
// * (Required) A short summary of the custom command to be shown when printing command line
|
||||
// * help, e.g. "rush --help".
|
||||
// */
|
||||
// "summary": "Example bulk custom command",
|
||||
|
||||
// /**
|
||||
// * A detailed description of the command to be shown when printing command line
|
||||
// * help (e.g. "rush --help my-command").
|
||||
// * If omitted, the "summary" text will be shown instead.
|
||||
// *
|
||||
// * Whenever you introduce commands/parameters, taking a little time to write meaningful
|
||||
// * documentation can make a big difference for the developer experience in your repo.
|
||||
// */
|
||||
// "description": "This is an example custom command that runs separately for each project",
|
||||
|
||||
// /**
|
||||
// * (Required) If true, then this command is safe to be run in parallel, i.e. executed
|
||||
// * simultaneously for multiple projects. Similar to "rush build", regardless of parallelism
|
||||
// * projects will not start processing until their dependencies have completed processing.
|
||||
// */
|
||||
// "enableParallelism": false,
|
||||
|
||||
// /**
|
||||
// * Normally Rush requires that each project's package.json has a "scripts" entry matching
|
||||
// * the custom command name. To disable this check, set "ignoreMissingScript" to true;
|
||||
// * projects with a missing definition will be skipped.
|
||||
// */
|
||||
// "ignoreMissingScript": false
|
||||
// },
|
||||
|
||||
// {
|
||||
// /**
|
||||
// * (Required) Determines the type of custom command.
|
||||
// * Rush's "global" commands are invoked once for the entire repo.
|
||||
// */
|
||||
// "commandKind": "global",
|
||||
|
||||
// "name": "my-global-command",
|
||||
// "summary": "Example global custom command",
|
||||
// "description": "This is an example custom command that runs once for the entire repo",
|
||||
|
||||
// /**
|
||||
// * A script that will be invoked using the OS shell. The working directory will be the folder
|
||||
// * that contains rush.json. If custom parameters are associated with this command, their
|
||||
// * values will be appended to the end of this string.
|
||||
// */
|
||||
// "shellCommand": "node common/scripts/my-global-command.js"
|
||||
// }
|
||||
],
|
||||
|
||||
/**
|
||||
* Custom "parameters" introduce new parameters for specified Rush command-line commands.
|
||||
* For example, you might define a "--production" parameter for the "rush build" command.
|
||||
*/
|
||||
"parameters": [
|
||||
// {
|
||||
// /**
|
||||
// * (Required) Determines the type of custom parameter.
|
||||
// * A "flag" is a custom command-line parameter whose presence acts as an on/off switch.
|
||||
// */
|
||||
// "parameterKind": "flag",
|
||||
|
||||
// /**
|
||||
// * (Required) The long name of the parameter. It must be lower-case and use dash delimiters.
|
||||
// */
|
||||
// "longName": "--my-flag",
|
||||
|
||||
// /**
|
||||
// * An optional alternative short name for the parameter. It must be a dash followed by a single
|
||||
// * lower-case or upper-case letter, which is case-sensitive.
|
||||
// *
|
||||
// * NOTE: The Rush developers recommend that automation scripts should always use the long name
|
||||
// * to improve readability. The short name is only intended as a convenience for humans.
|
||||
// * The alphabet letters run out quickly, and are difficult to memorize, so *only* use
|
||||
// * a short name if you expect the parameter to be needed very often in everyday operations.
|
||||
// */
|
||||
// "shortName": "-m",
|
||||
|
||||
// /**
|
||||
// * (Required) A long description to be shown in the command-line help.
|
||||
// *
|
||||
// * Whenever you introduce commands/parameters, taking a little time to write meaningful
|
||||
// * documentation can make a big difference for the developer experience in your repo.
|
||||
// */
|
||||
// "description": "A custom flag parameter that is passed to the scripts that are invoked when building projects",
|
||||
|
||||
// /**
|
||||
// * (Required) A list of custom commands and/or built-in Rush commands that this parameter may
|
||||
// * be used with. The parameter will be appended to the shell command that Rush invokes.
|
||||
// */
|
||||
// "associatedCommands": [ "build", "rebuild" ]
|
||||
// },
|
||||
|
||||
// {
|
||||
// /**
|
||||
// * (Required) Determines the type of custom parameter.
|
||||
// * A "flag" is a custom command-line parameter whose presence acts as an on/off switch.
|
||||
// */
|
||||
// "parameterKind": "choice",
|
||||
// "longName": "--my-choice",
|
||||
// "description": "A custom choice parameter for the \"my-global-command\" custom command",
|
||||
|
||||
// "associatedCommands": [ "my-global-command" ],
|
||||
|
||||
// /**
|
||||
// * Normally if a parameter is omitted from the command line, it will not be passed
|
||||
// * to the shell command. this value will be inserted by default. Whereas if a "defaultValue"
|
||||
// * is defined, the parameter will always be passed to the shell command, and will use the
|
||||
// * default value if unspecified. The value must be one of the defined alternatives.
|
||||
// */
|
||||
// "defaultValue": "vanilla",
|
||||
|
||||
// /**
|
||||
// * (Required) A list of alternative argument values that can be chosen for this parameter.
|
||||
// */
|
||||
// "alternatives": [
|
||||
// {
|
||||
// /**
|
||||
// * A token that is one of the alternatives that can be used with the choice parameter,
|
||||
// * e.g. "vanilla" in "--flavor vanilla".
|
||||
// */
|
||||
// "name": "vanilla",
|
||||
|
||||
// /**
|
||||
// * A detailed description for the alternative that can be shown in the command-line help.
|
||||
// *
|
||||
// * Whenever you introduce commands/parameters, taking a little time to write meaningful
|
||||
// * documentation can make a big difference for the developer experience in your repo.
|
||||
// */
|
||||
// "description": "Use the vanilla flavor (the default)"
|
||||
// },
|
||||
|
||||
// {
|
||||
// "name": "chocolate",
|
||||
// "description": "Use the chocolate flavor"
|
||||
// },
|
||||
|
||||
// {
|
||||
// "name": "strawberry",
|
||||
// "description": "Use the strawberry flavor"
|
||||
// }
|
||||
// ]
|
||||
// }
|
||||
]
|
||||
}
|
|
@ -1,43 +0,0 @@
|
|||
/**
|
||||
* This configuration file specifies NPM dependency version selections that affect all projects
|
||||
* in a Rush repo. For full documentation, please see https://rushjs.io
|
||||
*/
|
||||
{
|
||||
"$schema": "https://developer.microsoft.com/json-schemas/rush/v5/common-versions.schema.json",
|
||||
|
||||
/**
|
||||
* A table that specifies a "preferred version" for a dependency package. The "preferred version"
|
||||
* is typically used to hold an indirect dependency back to a specific version, however generally
|
||||
* it can be any SemVer range specifier (e.g. "~1.2.3"), and it will narrow any (compatible)
|
||||
* SemVer range specifier. See the Rush documentation for details about this feature.
|
||||
*/
|
||||
"preferredVersions": {
|
||||
|
||||
/**
|
||||
* When someone asks for "^1.0.0" make sure they get "1.2.3" when working in this repo,
|
||||
* instead of the latest version.
|
||||
*/
|
||||
// "some-library": "1.2.3"
|
||||
},
|
||||
|
||||
/**
|
||||
* The "rush check" command can be used to enforce that every project in the repo must specify
|
||||
* the same SemVer range for a given dependency. However, sometimes exceptions are needed.
|
||||
* The allowedAlternativeVersions table allows you to list other SemVer ranges that will be
|
||||
* accepted by "rush check" for a given dependency.
|
||||
*
|
||||
* IMPORTANT: THIS TABLE IS FOR *ADDITIONAL* VERSION RANGES THAT ARE ALTERNATIVES TO THE
|
||||
* USUAL VERSION (WHICH IS INFERRED BY LOOKING AT ALL PROJECTS IN THE REPO).
|
||||
* This design avoids unnecessary churn in this file.
|
||||
*/
|
||||
"allowedAlternativeVersions": {
|
||||
|
||||
/**
|
||||
* For example, allow some projects to use an older TypeScript compiler
|
||||
* (in addition to whatever "usual" version is being used by other projects in the repo):
|
||||
*/
|
||||
// "typescript": [
|
||||
// "~2.4.0"
|
||||
// ]
|
||||
}
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
/**
|
||||
* This is configuration file is used for advanced publishing configurations with Rush.
|
||||
* For full documentation, please see https://rushjs.io
|
||||
*/
|
||||
|
||||
/**
|
||||
* A list of version policy definitions. A "version policy" is a custom package versioning
|
||||
* strategy that affets "rush change", "rush version", and "rush publish". The strategy applies
|
||||
* to a set of projects that are specified using the "versionPolicyName" field in rush.json.
|
||||
*/
|
||||
[
|
||||
// {
|
||||
// /**
|
||||
// * (Required) Indicates the kind of version policy being defined ("lockStepVersion" or "individualVersion").
|
||||
// *
|
||||
// * The "individualVersion" mode specifies that the projects will use "individual versioning".
|
||||
// * This is the typical NPM model where each package has an independent version number
|
||||
// * and CHANGELOG.md file. Although a single CI definition is responsible for publishing the
|
||||
// * packages, they otherwise don't have any special relationship. The version bumping will
|
||||
// * depend on how developers answer the "rush change" questions for each package that
|
||||
// * is changed.
|
||||
// */
|
||||
// "definitionName": "individualVersion",
|
||||
// "policyName": "RepoPolicy",
|
||||
// /**
|
||||
// * (Optional) This can be used to enforce that all packages in the set must share a common
|
||||
// * major version number, e.g. because they are from the same major release branch.
|
||||
// * It can also be used to discourage people from accidentally making "MAJOR" SemVer changes
|
||||
// * inappropriately. The minor/patch version parts will be bumped independently according
|
||||
// * to the types of changes made to each project, according to the "rush change" command.
|
||||
// */
|
||||
// "lockedMajor": 0
|
||||
// }
|
||||
]
|
|
@ -1,52 +0,0 @@
|
|||
"use strict";
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
|
||||
// See the @microsoft/rush package's LICENSE file for license information.
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
// THIS FILE WAS GENERATED BY A TOOL. ANY MANUAL MODIFICATIONS WILL GET OVERWRITTEN WHENEVER RUSH IS UPGRADED.
|
||||
//
|
||||
// This script is intended for usage in an automated build environment where the Rush command may not have
|
||||
// been preinstalled, or may have an unpredictable version. This script will automatically install the version of Rush
|
||||
// specified in the rush.json configuration file (if not already installed), and then pass a command-line to it.
|
||||
// An example usage would be:
|
||||
//
|
||||
// node common/scripts/install-run-rush.js install
|
||||
//
|
||||
// For more information, see: https://rushjs.io/pages/maintainer/setup_new_repo/
|
||||
const path = require("path");
|
||||
const fs = require("fs");
|
||||
const install_run_1 = require("./install-run");
|
||||
const PACKAGE_NAME = '@microsoft/rush';
|
||||
function getRushVersion() {
|
||||
const rushJsonFolder = install_run_1.findRushJsonFolder();
|
||||
const rushJsonPath = path.join(rushJsonFolder, install_run_1.RUSH_JSON_FILENAME);
|
||||
try {
|
||||
const rushJsonContents = fs.readFileSync(rushJsonPath, 'utf-8');
|
||||
// Use a regular expression to parse out the rushVersion value because rush.json supports comments,
|
||||
// but JSON.parse does not and we don't want to pull in more dependencies than we need to in this script.
|
||||
const rushJsonMatches = rushJsonContents.match(/\"rushVersion\"\s*\:\s*\"([0-9a-zA-Z.+\-]+)\"/);
|
||||
return rushJsonMatches[1];
|
||||
}
|
||||
catch (e) {
|
||||
throw new Error(`Unable to determine the required version of Rush from rush.json (${rushJsonFolder}). ` +
|
||||
'The \'rushVersion\' field is either not assigned in rush.json or was specified ' +
|
||||
'using an unexpected syntax.');
|
||||
}
|
||||
}
|
||||
function run() {
|
||||
const [nodePath, /* Ex: /bin/node */ scriptPath, /* /repo/common/scripts/install-run-rush.js */ ...packageBinArgs /* [build, --to, myproject] */] = process.argv;
|
||||
if (!nodePath || !scriptPath) {
|
||||
throw new Error('Unexpected exception: could not detect node path or script path');
|
||||
}
|
||||
if (process.argv.length < 3) {
|
||||
console.log('Usage: install-run-rush.js <command> [args...]');
|
||||
console.log('Example: install-run-rush.js build --to myproject');
|
||||
process.exit(1);
|
||||
}
|
||||
install_run_1.runWithErrorAndStatusCode(() => {
|
||||
const version = getRushVersion();
|
||||
console.log(`The rush.json configuration requests Rush version ${version}`);
|
||||
return install_run_1.installAndRun(PACKAGE_NAME, version, 'rush', packageBinArgs);
|
||||
});
|
||||
}
|
||||
run();
|
||||
//# sourceMappingURL=install-run-rush.js.map
|
|
@ -1,399 +0,0 @@
|
|||
"use strict";
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
|
||||
// See the @microsoft/rush package's LICENSE file for license information.
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
// THIS FILE WAS GENERATED BY A TOOL. ANY MANUAL MODIFICATIONS WILL GET OVERWRITTEN WHENEVER RUSH IS UPGRADED.
|
||||
//
|
||||
// This script is intended for usage in an automated build environment where a Node tool may not have
|
||||
// been preinstalled, or may have an unpredictable version. This script will automatically install the specified
|
||||
// version of the specified tool (if not already installed), and then pass a command-line to it.
|
||||
// An example usage would be:
|
||||
//
|
||||
// node common/scripts/install-run.js qrcode@1.2.2 qrcode https://rushjs.io
|
||||
//
|
||||
// For more information, see: https://rushjs.io/pages/maintainer/setup_new_repo/
|
||||
const childProcess = require("child_process");
|
||||
const fs = require("fs");
|
||||
const os = require("os");
|
||||
const path = require("path");
|
||||
exports.RUSH_JSON_FILENAME = 'rush.json';
|
||||
const INSTALLED_FLAG_FILENAME = 'installed.flag';
|
||||
const NODE_MODULES_FOLDER_NAME = 'node_modules';
|
||||
const PACKAGE_JSON_FILENAME = 'package.json';
|
||||
/**
|
||||
* Parse a package specifier (in the form of name\@version) into name and version parts.
|
||||
*/
|
||||
function parsePackageSpecifier(rawPackageSpecifier) {
|
||||
rawPackageSpecifier = (rawPackageSpecifier || '').trim();
|
||||
const separatorIndex = rawPackageSpecifier.lastIndexOf('@');
|
||||
let name;
|
||||
let version = undefined;
|
||||
if (separatorIndex === 0) {
|
||||
// The specifier starts with a scope and doesn't have a version specified
|
||||
name = rawPackageSpecifier;
|
||||
}
|
||||
else if (separatorIndex === -1) {
|
||||
// The specifier doesn't have a version
|
||||
name = rawPackageSpecifier;
|
||||
}
|
||||
else {
|
||||
name = rawPackageSpecifier.substring(0, separatorIndex);
|
||||
version = rawPackageSpecifier.substring(separatorIndex + 1);
|
||||
}
|
||||
if (!name) {
|
||||
throw new Error(`Invalid package specifier: ${rawPackageSpecifier}`);
|
||||
}
|
||||
return { name, version };
|
||||
}
|
||||
/**
|
||||
* Resolve a package specifier to a static version
|
||||
*/
|
||||
function resolvePackageVersion(rushCommonFolder, { name, version }) {
|
||||
if (!version) {
|
||||
version = '*'; // If no version is specified, use the latest version
|
||||
}
|
||||
if (version.match(/^[a-zA-Z0-9\-\+\.]+$/)) {
|
||||
// If the version contains only characters that we recognize to be used in static version specifiers,
|
||||
// pass the version through
|
||||
return version;
|
||||
}
|
||||
else {
|
||||
// version resolves to
|
||||
try {
|
||||
const rushTempFolder = ensureAndJoinPath(rushCommonFolder, 'temp');
|
||||
const sourceNpmrcFolder = path.join(rushCommonFolder, 'config', 'rush');
|
||||
syncNpmrc(sourceNpmrcFolder, rushTempFolder);
|
||||
const npmPath = getNpmPath();
|
||||
// This returns something that looks like:
|
||||
// @microsoft/rush@3.0.0 '3.0.0'
|
||||
// @microsoft/rush@3.0.1 '3.0.1'
|
||||
// ...
|
||||
// @microsoft/rush@3.0.20 '3.0.20'
|
||||
// <blank line>
|
||||
const npmVersionSpawnResult = childProcess.spawnSync(npmPath, ['view', `${name}@${version}`, 'version', '--no-update-notifier'], {
|
||||
cwd: rushTempFolder,
|
||||
stdio: []
|
||||
});
|
||||
if (npmVersionSpawnResult.status !== 0) {
|
||||
throw new Error(`"npm view" returned error code ${npmVersionSpawnResult.status}`);
|
||||
}
|
||||
const npmViewVersionOutput = npmVersionSpawnResult.stdout.toString();
|
||||
const versionLines = npmViewVersionOutput.split('\n').filter((line) => !!line);
|
||||
const latestVersion = versionLines[versionLines.length - 1];
|
||||
if (!latestVersion) {
|
||||
throw new Error('No versions found for the specified version range.');
|
||||
}
|
||||
const versionMatches = latestVersion.match(/^.+\s\'(.+)\'$/);
|
||||
if (!versionMatches) {
|
||||
throw new Error(`Invalid npm output ${latestVersion}`);
|
||||
}
|
||||
return versionMatches[1];
|
||||
}
|
||||
catch (e) {
|
||||
throw new Error(`Unable to resolve version ${version} of package ${name}: ${e}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
let _npmPath = undefined;
|
||||
/**
|
||||
* Get the absolute path to the npm executable
|
||||
*/
|
||||
function getNpmPath() {
|
||||
if (!_npmPath) {
|
||||
try {
|
||||
if (os.platform() === 'win32') {
|
||||
// We're on Windows
|
||||
const whereOutput = childProcess.execSync('where npm', { stdio: [] }).toString();
|
||||
const lines = whereOutput.split(os.EOL).filter((line) => !!line);
|
||||
// take the last result, we are looking for a .cmd command
|
||||
// see https://github.com/Microsoft/web-build-tools/issues/759
|
||||
_npmPath = lines[lines.length - 1];
|
||||
}
|
||||
else {
|
||||
// We aren't on Windows - assume we're on *NIX or Darwin
|
||||
_npmPath = childProcess.execSync('which npm', { stdio: [] }).toString();
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
throw new Error(`Unable to determine the path to the NPM tool: ${e}`);
|
||||
}
|
||||
_npmPath = _npmPath.trim();
|
||||
if (!fs.existsSync(_npmPath)) {
|
||||
throw new Error('The NPM executable does not exist');
|
||||
}
|
||||
}
|
||||
return _npmPath;
|
||||
}
|
||||
exports.getNpmPath = getNpmPath;
|
||||
let _rushJsonFolder;
|
||||
/**
|
||||
* Find the absolute path to the folder containing rush.json
|
||||
*/
|
||||
function findRushJsonFolder() {
|
||||
if (!_rushJsonFolder) {
|
||||
let basePath = __dirname;
|
||||
let tempPath = __dirname;
|
||||
do {
|
||||
const testRushJsonPath = path.join(basePath, exports.RUSH_JSON_FILENAME);
|
||||
if (fs.existsSync(testRushJsonPath)) {
|
||||
_rushJsonFolder = basePath;
|
||||
break;
|
||||
}
|
||||
else {
|
||||
basePath = tempPath;
|
||||
}
|
||||
} while (basePath !== (tempPath = path.dirname(basePath))); // Exit the loop when we hit the disk root
|
||||
if (!_rushJsonFolder) {
|
||||
throw new Error('Unable to find rush.json.');
|
||||
}
|
||||
}
|
||||
return _rushJsonFolder;
|
||||
}
|
||||
exports.findRushJsonFolder = findRushJsonFolder;
|
||||
/**
|
||||
* Create missing directories under the specified base directory, and return the resolved directory.
|
||||
*
|
||||
* Does not support "." or ".." path segments.
|
||||
* Assumes the baseFolder exists.
|
||||
*/
|
||||
function ensureAndJoinPath(baseFolder, ...pathSegments) {
|
||||
let joinedPath = baseFolder;
|
||||
try {
|
||||
for (let pathSegment of pathSegments) {
|
||||
pathSegment = pathSegment.replace(/[\\\/]/g, '+');
|
||||
joinedPath = path.join(joinedPath, pathSegment);
|
||||
if (!fs.existsSync(joinedPath)) {
|
||||
fs.mkdirSync(joinedPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
throw new Error(`Error building local installation folder (${path.join(baseFolder, ...pathSegments)}): ${e}`);
|
||||
}
|
||||
return joinedPath;
|
||||
}
|
||||
/**
|
||||
* As a workaround, _syncNpmrc() copies the .npmrc file to the target folder, and also trims
|
||||
* unusable lines from the .npmrc file. If the source .npmrc file not exist, then _syncNpmrc()
|
||||
* will delete an .npmrc that is found in the target folder.
|
||||
*
|
||||
* Why are we trimming the .npmrc lines? NPM allows environment variables to be specified in
|
||||
* the .npmrc file to provide different authentication tokens for different registry.
|
||||
* However, if the environment variable is undefined, it expands to an empty string, which
|
||||
* produces a valid-looking mapping with an invalid URL that causes an error. Instead,
|
||||
* we'd prefer to skip that line and continue looking in other places such as the user's
|
||||
* home directory.
|
||||
*
|
||||
* IMPORTANT: THIS CODE SHOULD BE KEPT UP TO DATE WITH Utilities._syncNpmrc()
|
||||
*/
|
||||
function syncNpmrc(sourceNpmrcFolder, targetNpmrcFolder) {
|
||||
const sourceNpmrcPath = path.join(sourceNpmrcFolder, '.npmrc');
|
||||
const targetNpmrcPath = path.join(targetNpmrcFolder, '.npmrc');
|
||||
try {
|
||||
if (fs.existsSync(sourceNpmrcPath)) {
|
||||
let npmrcFileLines = fs.readFileSync(sourceNpmrcPath).toString().split('\n');
|
||||
npmrcFileLines = npmrcFileLines.map((line) => (line || '').trim());
|
||||
const resultLines = [];
|
||||
// Trim out lines that reference environment variables that aren't defined
|
||||
for (const line of npmrcFileLines) {
|
||||
// This finds environment variable tokens that look like "${VAR_NAME}"
|
||||
const regex = /\$\{([^\}]+)\}/g;
|
||||
const environmentVariables = line.match(regex);
|
||||
let lineShouldBeTrimmed = false;
|
||||
if (environmentVariables) {
|
||||
for (const token of environmentVariables) {
|
||||
// Remove the leading "${" and the trailing "}" from the token
|
||||
const environmentVariableName = token.substring(2, token.length - 1);
|
||||
if (!process.env[environmentVariableName]) {
|
||||
lineShouldBeTrimmed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (lineShouldBeTrimmed) {
|
||||
// Example output:
|
||||
// "; MISSING ENVIRONMENT VARIABLE: //my-registry.com/npm/:_authToken=${MY_AUTH_TOKEN}"
|
||||
resultLines.push('; MISSING ENVIRONMENT VARIABLE: ' + line);
|
||||
}
|
||||
else {
|
||||
resultLines.push(line);
|
||||
}
|
||||
}
|
||||
fs.writeFileSync(targetNpmrcPath, resultLines.join(os.EOL));
|
||||
}
|
||||
else if (fs.existsSync(targetNpmrcPath)) {
|
||||
// If the source .npmrc doesn't exist and there is one in the target, delete the one in the target
|
||||
fs.unlinkSync(targetNpmrcPath);
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
throw new Error(`Error syncing .npmrc file: ${e}`);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Detects if the package in the specified directory is installed
|
||||
*/
|
||||
function isPackageAlreadyInstalled(packageInstallFolder) {
|
||||
try {
|
||||
const flagFilePath = path.join(packageInstallFolder, INSTALLED_FLAG_FILENAME);
|
||||
if (!fs.existsSync(flagFilePath)) {
|
||||
return false;
|
||||
}
|
||||
const fileContents = fs.readFileSync(flagFilePath).toString();
|
||||
return fileContents.trim() === process.version;
|
||||
}
|
||||
catch (e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Removes the following files and directories under the specified folder path:
|
||||
* - installed.flag
|
||||
* -
|
||||
* - node_modules
|
||||
*/
|
||||
function cleanInstallFolder(rushCommonFolder, packageInstallFolder) {
|
||||
try {
|
||||
const flagFile = path.resolve(packageInstallFolder, INSTALLED_FLAG_FILENAME);
|
||||
if (fs.existsSync(flagFile)) {
|
||||
fs.unlinkSync(flagFile);
|
||||
}
|
||||
const packageLockFile = path.resolve(packageInstallFolder, 'package-lock.json');
|
||||
if (fs.existsSync(packageLockFile)) {
|
||||
fs.unlinkSync(packageLockFile);
|
||||
}
|
||||
const nodeModulesFolder = path.resolve(packageInstallFolder, NODE_MODULES_FOLDER_NAME);
|
||||
if (fs.existsSync(nodeModulesFolder)) {
|
||||
const rushRecyclerFolder = ensureAndJoinPath(rushCommonFolder, 'temp', 'rush-recycler', `install-run-${Date.now().toString()}`);
|
||||
fs.renameSync(nodeModulesFolder, rushRecyclerFolder);
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
throw new Error(`Error cleaning the package install folder (${packageInstallFolder}): ${e}`);
|
||||
}
|
||||
}
|
||||
function createPackageJson(packageInstallFolder, name, version) {
|
||||
try {
|
||||
const packageJsonContents = {
|
||||
'name': 'ci-rush',
|
||||
'version': '0.0.0',
|
||||
'dependencies': {
|
||||
[name]: version
|
||||
},
|
||||
'description': 'DON\'T WARN',
|
||||
'repository': 'DON\'T WARN',
|
||||
'license': 'MIT'
|
||||
};
|
||||
const packageJsonPath = path.join(packageInstallFolder, PACKAGE_JSON_FILENAME);
|
||||
fs.writeFileSync(packageJsonPath, JSON.stringify(packageJsonContents, undefined, 2));
|
||||
}
|
||||
catch (e) {
|
||||
throw new Error(`Unable to create package.json: ${e}`);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Run "npm install" in the package install folder.
|
||||
*/
|
||||
function installPackage(packageInstallFolder, name, version) {
|
||||
try {
|
||||
console.log(`Installing ${name}...`);
|
||||
const npmPath = getNpmPath();
|
||||
const result = childProcess.spawnSync(npmPath, ['install'], {
|
||||
stdio: 'inherit',
|
||||
cwd: packageInstallFolder,
|
||||
env: process.env
|
||||
});
|
||||
if (result.status !== 0) {
|
||||
throw new Error('"npm install" encountered an error');
|
||||
}
|
||||
console.log(`Successfully installed ${name}@${version}`);
|
||||
}
|
||||
catch (e) {
|
||||
throw new Error(`Unable to install package: ${e}`);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Get the ".bin" path for the package.
|
||||
*/
|
||||
function getBinPath(packageInstallFolder, binName) {
|
||||
const binFolderPath = path.resolve(packageInstallFolder, NODE_MODULES_FOLDER_NAME, '.bin');
|
||||
const resolvedBinName = (os.platform() === 'win32') ? `${binName}.cmd` : binName;
|
||||
return path.resolve(binFolderPath, resolvedBinName);
|
||||
}
|
||||
/**
|
||||
* Write a flag file to the package's install directory, signifying that the install was successful.
|
||||
*/
|
||||
function writeFlagFile(packageInstallFolder) {
|
||||
try {
|
||||
const flagFilePath = path.join(packageInstallFolder, INSTALLED_FLAG_FILENAME);
|
||||
fs.writeFileSync(flagFilePath, process.version);
|
||||
}
|
||||
catch (e) {
|
||||
throw new Error(`Unable to create installed.flag file in ${packageInstallFolder}`);
|
||||
}
|
||||
}
|
||||
function installAndRun(packageName, packageVersion, packageBinName, packageBinArgs) {
|
||||
const rushJsonFolder = findRushJsonFolder();
|
||||
const rushCommonFolder = path.join(rushJsonFolder, 'common');
|
||||
const packageInstallFolder = ensureAndJoinPath(rushCommonFolder, 'temp', 'install-run', `${packageName}@${packageVersion}`);
|
||||
if (!isPackageAlreadyInstalled(packageInstallFolder)) {
|
||||
// The package isn't already installed
|
||||
cleanInstallFolder(rushCommonFolder, packageInstallFolder);
|
||||
const sourceNpmrcFolder = path.join(rushCommonFolder, 'config', 'rush');
|
||||
syncNpmrc(sourceNpmrcFolder, packageInstallFolder);
|
||||
createPackageJson(packageInstallFolder, packageName, packageVersion);
|
||||
installPackage(packageInstallFolder, packageName, packageVersion);
|
||||
writeFlagFile(packageInstallFolder);
|
||||
}
|
||||
const statusMessage = `Invoking "${packageBinName} ${packageBinArgs.join(' ')}"`;
|
||||
const statusMessageLine = new Array(statusMessage.length + 1).join('-');
|
||||
console.log(os.EOL + statusMessage + os.EOL + statusMessageLine + os.EOL);
|
||||
const binPath = getBinPath(packageInstallFolder, packageBinName);
|
||||
const result = childProcess.spawnSync(binPath, packageBinArgs, {
|
||||
stdio: 'inherit',
|
||||
cwd: process.cwd(),
|
||||
env: process.env
|
||||
});
|
||||
return result.status;
|
||||
}
|
||||
exports.installAndRun = installAndRun;
|
||||
function runWithErrorAndStatusCode(fn) {
|
||||
process.exitCode = 1;
|
||||
try {
|
||||
const exitCode = fn();
|
||||
process.exitCode = exitCode;
|
||||
}
|
||||
catch (e) {
|
||||
console.error(os.EOL + os.EOL + e.toString() + os.EOL + os.EOL);
|
||||
}
|
||||
}
|
||||
exports.runWithErrorAndStatusCode = runWithErrorAndStatusCode;
|
||||
function run() {
|
||||
const [nodePath, /* Ex: /bin/node */ scriptPath, /* /repo/common/scripts/install-run-rush.js */ rawPackageSpecifier, /* qrcode@^1.2.0 */ packageBinName, /* qrcode */ ...packageBinArgs /* [-f, myproject/lib] */] = process.argv;
|
||||
if (!nodePath) {
|
||||
throw new Error('Unexpected exception: could not detect node path');
|
||||
}
|
||||
if (path.basename(scriptPath).toLowerCase() !== 'install-run.js') {
|
||||
// If install-run.js wasn't directly invoked, don't execute the rest of this function. Return control
|
||||
// to the script that (presumably) imported this file
|
||||
return;
|
||||
}
|
||||
if (process.argv.length < 4) {
|
||||
console.log('Usage: install-run.js <package>@<version> <command> [args...]');
|
||||
console.log('Example: install-run.js qrcode@1.2.2 qrcode https://rushjs.io');
|
||||
process.exit(1);
|
||||
}
|
||||
runWithErrorAndStatusCode(() => {
|
||||
const rushJsonFolder = findRushJsonFolder();
|
||||
const rushCommonFolder = ensureAndJoinPath(rushJsonFolder, 'common');
|
||||
const packageSpecifier = parsePackageSpecifier(rawPackageSpecifier);
|
||||
const name = packageSpecifier.name;
|
||||
const version = resolvePackageVersion(rushCommonFolder, packageSpecifier);
|
||||
if (packageSpecifier.version !== version) {
|
||||
console.log(`Resolved to ${name}@${version}`);
|
||||
}
|
||||
return installAndRun(name, version, packageBinName, packageBinArgs);
|
||||
});
|
||||
}
|
||||
run();
|
||||
//# sourceMappingURL=install-run.js.map
|
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
|
@ -1,21 +0,0 @@
|
|||
{
|
||||
"name": "{{name}}-monorepo",
|
||||
"private": true,
|
||||
"version": "0.0.1",
|
||||
"description": "{{name}} Monorepo",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": ""
|
||||
},
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
"build": "node common/scripts/install-run-rush.js build",
|
||||
"change": "node common/scripts/install-run-rush.js change",
|
||||
"checkchange": "node common/scripts/install-run-rush.js change -v",
|
||||
"test": "node common/scripts/install-run-rush.js test",
|
||||
"update": "node common/scripts/install-run-rush.js update",
|
||||
"postinstall": "node common/scripts/install-run-rush.js install",
|
||||
"add-package": "cd scripts && npm run add-package",
|
||||
"upgrade-repo": "cd scripts && npm run upgrade-repo"
|
||||
}
|
||||
}
|
|
@ -1,284 +0,0 @@
|
|||
/**
|
||||
* This is the main configuration file for Rush.
|
||||
* For full documentation, please see https://rushjs.io
|
||||
*/
|
||||
{
|
||||
"$schema": "https://developer.microsoft.com/json-schemas/rush/v5/rush.schema.json",
|
||||
|
||||
/**
|
||||
* (Required) This specifies the version of the Rush engine to be used in this repo.
|
||||
* Rush's "version selector" feature ensures that the globally installed tool will
|
||||
* behave like this release, regardless of which version is installed globally.
|
||||
*
|
||||
* The common/scripts/install-run-rush.js automation script also uses this version.
|
||||
*
|
||||
* NOTE: If you upgrade to a new major version of Rush, you should replace the "v5"
|
||||
* path segment in the "$schema" field for all your Rush config files. This will ensure
|
||||
* correct error-underlining and tab-completion for editors such as VS Code.
|
||||
*/
|
||||
"rushVersion": "5.6.3",
|
||||
|
||||
/**
|
||||
* The next field selects which package manager should be installed and determines its version.
|
||||
* Rush installs its own local copy of the package manager to ensure that your build process
|
||||
* is fully isolated from whatever tools are present in the local environment.
|
||||
*
|
||||
* Specify one of: "pnpmVersion", "npmVersion", or "yarnVersion". See the Rush documentation
|
||||
* for details about these alternatives.
|
||||
*/
|
||||
"pnpmVersion": "3.1.0",
|
||||
|
||||
/**
|
||||
* Options that are only used when the PNPM package manager is selected
|
||||
*/
|
||||
"pnpmOptions": {
|
||||
/**
|
||||
* If true, then Rush will add the "--strict-peer-dependencies" option when invoking PNPM.
|
||||
* This causes "rush install" to fail if there are unsatisfied peer dependencies, which is
|
||||
* an invalid state that can cause build failures or incompatible dependency versions.
|
||||
* (For historical reasons, JavaScript package managers generally do not treat this invalid
|
||||
* state as an error.)
|
||||
*/
|
||||
"strictPeerDependencies": true
|
||||
},
|
||||
|
||||
/**
|
||||
* Specify a SemVer range to ensure developers use a NodeJS version that is appropriate
|
||||
* for your repo.
|
||||
*/
|
||||
"nodeSupportedVersionRange": ">=8.9.4 <9.0.0 || >=10.9.0 <12.0.0",
|
||||
|
||||
/**
|
||||
* This feature helps you to review and approve new packages before they are introduced
|
||||
* to your monorepo. For example, you may be concerned about licensing, code quality,
|
||||
* performance, or simply accumulating too many libraries with overlapping functionality.
|
||||
* The approvals are tracked in two config files "browser-approved-packages.json"
|
||||
* and "nonbrowser-approved-packages.json". See the Rush documentation for details.
|
||||
*/
|
||||
// "approvedPackagesPolicy": {
|
||||
// /**
|
||||
// * The review categories allow you to say for example "This library is approved for usage
|
||||
// * in prototypes, but not in production code."
|
||||
// *
|
||||
// * Each project can be associated with one review category, by assigning the "reviewCategory" field
|
||||
// * in the "projects" section of rush.json. The approval is then recorded in the files
|
||||
// * "common/config/rush/browser-approved-packages.json" and "nonbrowser-approved-packages.json"
|
||||
// * which are automatically generated during "rush update".
|
||||
// *
|
||||
// * Designate categories with whatever granularity is appropriate for your review process,
|
||||
// * or you could just have a single category called "default".
|
||||
// */
|
||||
// "reviewCategories": [
|
||||
// // Some example categories:
|
||||
// "production", // projects that ship to production
|
||||
// "tools", // non-shipping projects that are part of the developer toolchain
|
||||
// "prototypes" // experiments that should mostly be ignored by the review process
|
||||
// ],
|
||||
//
|
||||
// /**
|
||||
// * A list of NPM package scopes that will be excluded from review.
|
||||
// * We recommend to exclude TypeScript typings (the "@types" scope), because
|
||||
// * if the underlying package was already approved, this would imply that the typings
|
||||
// * are also approved.
|
||||
// */
|
||||
// // "ignoredNpmScopes": [ "@types" ]
|
||||
// },
|
||||
|
||||
/**
|
||||
* Large monorepos can become intimidating for newcomers if project folder paths don't follow
|
||||
* a consistent and recognizable pattern. When the system allows nested folder trees,
|
||||
* we've found that teams will often use subfolders to create islands that isolate
|
||||
* their work from others ("shipping the org"). This hinders collaboration and code sharing.
|
||||
*
|
||||
* The Rush developers recommend a "category folder" model, where buildable project folders
|
||||
* must always be exactly two levels below the repo root. The parent folder acts as the category.
|
||||
* This provides a basic facility for grouping related projects (e.g. "apps", "libaries",
|
||||
* "tools", "prototypes") while still encouraging teams to organize their projects into
|
||||
* a unified taxonomy. Limiting to 2 levels seems very restrictive at first, but if you have
|
||||
* 20 categories and 20 projects in each category, this scheme can easily accommodate hundreds
|
||||
* of projects. In practice, you will find that the folder hierarchy needs to be rebalanced
|
||||
* occasionally, but if that's painful, it's a warning sign that your development style may
|
||||
* discourage refactoring. Reorganizing the categories should be an enlightening discussion
|
||||
* that brings people together, and maybe also identifies poor coding practices (e.g. file
|
||||
* references that reach into other project's folders without using NodeJS module resolution).
|
||||
*
|
||||
* The defaults are projectFolderMinDepth=1 and projectFolderMaxDepth=2.
|
||||
*
|
||||
* To remove these restrictions, you could set projectFolderMinDepth=1
|
||||
* and set projectFolderMaxDepth to a large number.
|
||||
*/
|
||||
// "projectFolderMinDepth": 1,
|
||||
// "projectFolderMaxDepth": 2,
|
||||
|
||||
/**
|
||||
* Event hooks are customized script actions that Rush executes when specific events occur
|
||||
*/
|
||||
"eventHooks": {
|
||||
/**
|
||||
* The list of shell commands to run before the Rush installation starts
|
||||
*/
|
||||
"preRushInstall": [],
|
||||
|
||||
/**
|
||||
* The list of shell commands to run after the Rush installation finishes
|
||||
*/
|
||||
"postRushInstall": [],
|
||||
|
||||
/**
|
||||
* The list of shell commands to run before the Rush build command starts
|
||||
*/
|
||||
"preRushBuild": [],
|
||||
|
||||
/**
|
||||
* The list of shell commands to run after the Rush build command finishes
|
||||
*/
|
||||
"postRushBuild": []
|
||||
},
|
||||
|
||||
/**
|
||||
* If you would like the version specifiers for your dependencies to be consistent, then
|
||||
* uncomment this line. This is effectively similar to running "rush check" before any
|
||||
* of the following commands:
|
||||
*
|
||||
* rush install, rush update, rush link, rush version, rush publish
|
||||
*
|
||||
* In some cases you may want this turned on, but need to allow certain packages to use a different
|
||||
* version. In those cases, you will need to add an entry to the "allowedAlternateVersions"
|
||||
* section of the common-versions.json.
|
||||
*/
|
||||
// "ensureConsistentVersions": true,
|
||||
|
||||
/**
|
||||
* If you use Git as your version control system, this section has some additional
|
||||
* optional features you can use.
|
||||
*/
|
||||
"gitPolicy": {
|
||||
/**
|
||||
* Work at a big company? Tired of finding Git commits at work with unprofessional Git
|
||||
* emails such as "beer-lover@my-college.edu"? Rush can validate people's Git email address
|
||||
* before they get started.
|
||||
*
|
||||
* Define a list of regular expressions describing allowable e-mail patterns for Git commits.
|
||||
* They are case-insensitive anchored JavaScript RegExps. Example: ".*@example\.com"
|
||||
*
|
||||
* IMPORTANT: Because these are regular expressions encoded as JSON string literals,
|
||||
* RegExp escapes need two backspashes, and ordinary periods should be "\\.".
|
||||
*/
|
||||
// "allowedEmailRegExps": [
|
||||
// "[^@]+@users\\.noreply\\.github\\.com",
|
||||
// "travis@example\\.org"
|
||||
// ],
|
||||
/**
|
||||
* When Rush reports that the address is malformed, the notice can include an example
|
||||
* of a recommended email. Make sure it conforms to one of the allowedEmailRegExps
|
||||
* expressions.
|
||||
*/
|
||||
// "sampleEmail": "mrexample@users.noreply.github.com"
|
||||
},
|
||||
|
||||
"repository": {
|
||||
/**
|
||||
* This setting is sometimes needed when using "rush change" with multiple Git remotes.
|
||||
* It specifies the remote url for the official Git repository. If this URL is provided,
|
||||
* "rush change" will use it to find the right remote to compare against.
|
||||
*/
|
||||
// "url": "https://github.com/microsoft/rush-example"
|
||||
},
|
||||
|
||||
/**
|
||||
* Installation variants allow you to maintain a parallel set of configuration files that can be
|
||||
* used to build the entire monorepo with an alternate set of dependencies. For example, suppose
|
||||
* you upgrade all your projects to use a new release of an important framework, but during a transition period
|
||||
* you intend to maintain compability with the old release. In this situation, you probably want your
|
||||
* CI validation to build the entire repo twice: once with the old release, and once with the new release.
|
||||
*
|
||||
* Rush "installation variants" correspond to sets of config files located under this folder:
|
||||
*
|
||||
* common/config/rush/variants/<variant_name>
|
||||
*
|
||||
* The variant folder can contain an alternate common-versions.json file. Its "preferredVersions" field can be used
|
||||
* to select older versions of dependencies (within a loose SemVer range specified in your package.json files).
|
||||
* To install a variant, run "rush install --variant <variant_name>".
|
||||
*
|
||||
* For more details and instructions, see this article: https://rushjs.io/pages/advanced/installation_variants/
|
||||
*/
|
||||
"variants": [
|
||||
// {
|
||||
// /**
|
||||
// * The folder name for this variant.
|
||||
// */
|
||||
// "variantName": "old-sdk",
|
||||
//
|
||||
// /**
|
||||
// * An informative description
|
||||
// */
|
||||
// "description": "Build this repo using the previous release of the SDK"
|
||||
// }
|
||||
],
|
||||
|
||||
/**
|
||||
* Rush can collect anonymous telemetry about everyday developer activity such as
|
||||
* success/failure of installs, builds, and other operations. You can use this to identify
|
||||
* problems with your toolchain or Rush itself. THIS TELEMETRY IS NOT SHARED WITH MICROSOFT.
|
||||
* It is written into JSON files in the common/temp folder. It's up to you to write scripts
|
||||
* that read these JSON files and do something with them. These scripts are typically registered
|
||||
* in the "eventHooks" section.
|
||||
*/
|
||||
// "telemetryEnabled": false,
|
||||
|
||||
/**
|
||||
* Allows creation of hotfix changes. This feature is experimental so it is disabled by default.
|
||||
*/
|
||||
// "hotfixChangeEnabled": false,
|
||||
|
||||
/**
|
||||
* (Required) This is the inventory of projects to be managed by Rush.
|
||||
*
|
||||
* Rush does not automatically scan for projects using wildcards, for a few reasons:
|
||||
* 1. Depth-first scans are expensive, particularly when tools need to repeatedly collect the list.
|
||||
* 2. On a caching CI machine, scans can accidentally pick up files left behind from a previous build.
|
||||
* 3. It's useful to have a centralized inventory of all projects and their important metadata.
|
||||
*/
|
||||
"projects": [
|
||||
{
|
||||
/**
|
||||
* The NPM package name of the project (must match package.json)
|
||||
*/
|
||||
"packageName": "{{name}}-scripts",
|
||||
|
||||
/**
|
||||
* The path to the project folder, relative to the rush.json config file.
|
||||
*/
|
||||
"projectFolder": "scripts"
|
||||
|
||||
/**
|
||||
* A flag indicating that changes to this project will be published to npm, which affects
|
||||
* the Rush change and publish workflows. The default value is false.
|
||||
* NOTE: "versionPolicyName" and "shouldPublish" are alternatives; you cannot specify them both.
|
||||
*/
|
||||
// "shouldPublish": true,
|
||||
|
||||
// /**
|
||||
// * An optional category for usage in the "browser-approved-packages.json"
|
||||
// * and "nonbrowser-approved-packages.json" files. The value must be one of the
|
||||
// * strings from the "reviewCategories" defined above.
|
||||
// */
|
||||
// "reviewCategory": "production",
|
||||
|
||||
// /**
|
||||
// * A list of local projects that appear as devDependencies for this project, but cannot be
|
||||
// * locally linked because it would create a cyclic dependency; instead, the last published
|
||||
// * version will be installed in the Common folder.
|
||||
// */
|
||||
// "cyclicDependencyProjects": [
|
||||
// // "my-toolchain"
|
||||
// ],
|
||||
|
||||
// /**
|
||||
// * If true, then this project will be ignored by the "rush check" command.
|
||||
// * The default value is false.
|
||||
// */
|
||||
// "skipRushCheck": false,
|
||||
}
|
||||
]
|
||||
}
|
|
@ -1,3 +0,0 @@
|
|||
// @ts-check
|
||||
const { taskPresets } = require('just-scripts');
|
||||
module.exports = taskPresets.monorepo;
|
|
@ -1,23 +0,0 @@
|
|||
{
|
||||
"name": "{{name}}-scripts",
|
||||
"private": true,
|
||||
"version": "0.0.1",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"add-package": "just add-package --cwd ../",
|
||||
"upgrade-repo": "just upgrade-repo --cwd ../",
|
||||
"build": ""
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"just-task": "^0.9.0",
|
||||
"just-scripts": "^0.14.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"just-stack-single-lib": ">=0.1.0",
|
||||
"just-stack-uifabric": ">=0.1.0"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
CHANGELOG.*
|
||||
*.log
|
||||
node_modules
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
{
|
||||
"name": "just-stack-react",
|
||||
"version": "0.2.0",
|
||||
"license": "MIT",
|
||||
"main": "index.js",
|
||||
"dependencies": {
|
||||
"@babel/core": "^7.5.5",
|
||||
"@babel/preset-env": "^7.5.5",
|
||||
"@babel/preset-react": "^7.0.0",
|
||||
"@babel/preset-typescript": "^7.3.3",
|
||||
"@types/jest": "^24.0.16",
|
||||
"@types/react": "^16.8.24",
|
||||
"@types/react-dom": "^16.8.5",
|
||||
"acorn": "^6.0.0",
|
||||
"autoprefixer": "^9.4.5",
|
||||
"beachball": "^1.11.5",
|
||||
"css-loader": "^2.1.0",
|
||||
"file-loader": "^3.0.1",
|
||||
"fork-ts-checker-webpack-plugin": "^1.2.0",
|
||||
"fs-extra": "^7.0.1",
|
||||
"glob": "^7.1.3",
|
||||
"html-webpack-plugin": "^3.2.0",
|
||||
"jest": "^24.8.0",
|
||||
"jest-expect-message": "^1.0.2",
|
||||
"node-sass": "^4.11.0",
|
||||
"plop": "^2.4.0",
|
||||
"postcss": "^7.0.13",
|
||||
"postcss-loader": "^3.0.0",
|
||||
"style-loader": "^0.23.1",
|
||||
"ts-loader": "^5.3.3",
|
||||
"tslib": "^1.9.3",
|
||||
"typescript": "^3.5.3",
|
||||
"webpack": "~4.29.5",
|
||||
"webpack-cli": "^3.2.1",
|
||||
"webpack-dev-server": "^3.1.14"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
module.exports = {
|
||||
presets: ['@babel/preset-env', '@babel/preset-typescript', '@babel/preset-react']
|
||||
};
|
|
@ -0,0 +1,4 @@
|
|||
node_modules
|
||||
lib
|
||||
lib-commonjs
|
||||
dist
|
|
@ -0,0 +1,5 @@
|
|||
module.exports = {
|
||||
clearMocks: true,
|
||||
testEnvironment: 'jsdom',
|
||||
testMatch: ['<rootDir>/src/**/__tests__/**/*.[jt]s?(x)', '<rootDir>/src/**/?(*.)+(spec|test).[tj]s?(x)']
|
||||
};
|
|
@ -1,3 +1,3 @@
|
|||
// @ts-check
|
||||
const { taskPresets } = require('just-scripts');
|
||||
module.exports = taskPresets.lib;
|
||||
|
||||
taskPresets.webapp();
|
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"name": "{{name}}-single",
|
||||
"version": "0.1.0",
|
||||
"license": "MIT",
|
||||
"main": "lib-commonjs/index.js",
|
||||
"module": "lib/index.js",
|
||||
"scripts": {
|
||||
"build": "just-scripts build",
|
||||
"just": "just-scripts",
|
||||
"start": "just-scripts start",
|
||||
"test": "just-scripts test",
|
||||
"change": "npx beachball change",
|
||||
"gen": "npx plop"
|
||||
},
|
||||
"dependencies": {
|
||||
"react": "^16.8.6",
|
||||
"react-dom": "^16.8.6"
|
||||
},
|
||||
"devDependencies": {
|
||||
"just-stack-react": "^0.1.0",
|
||||
"just-scripts": "^0.26.0"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
import React from 'react';
|
||||
|
||||
export interface \{{pascalCase componentName}}Props {
|
||||
// Fill in props here
|
||||
}
|
||||
|
||||
export const \{{pascalCase componentName}} = (props: \{{pascalCase componentName}}Props) => {
|
||||
return (
|
||||
<div>
|
||||
{/* TODO */}
|
||||
</div>
|
||||
);
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
module.exports = plop => {
|
||||
plop.setGenerator('component', {
|
||||
prompts: [
|
||||
{
|
||||
type: 'input',
|
||||
name: 'componentName',
|
||||
message: 'Name of the component (will be converted to PascalCase): '
|
||||
}
|
||||
],
|
||||
|
||||
actions: [
|
||||
{
|
||||
type: 'add',
|
||||
templateFile: 'plop-templates/component/component.tsx.hbs',
|
||||
path: 'src/components/\{{pascalCase componentName}}.tsx'
|
||||
}
|
||||
]
|
||||
});
|
||||
};
|
|
@ -0,0 +1,9 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"/>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,3 @@
|
|||
import React from 'react';
|
||||
|
||||
export default () => <div>This is an application</div>;
|
|
@ -0,0 +1,7 @@
|
|||
import { hello } from '../helloworld';
|
||||
describe('hello', () => {
|
||||
it('says hello', () => {
|
||||
const result = hello('world');
|
||||
expect(result).toBe('hello world');
|
||||
});
|
||||
});
|
|
@ -0,0 +1,3 @@
|
|||
export const hello = (name: string) => {
|
||||
return `hello ${name}`;
|
||||
};
|
|
@ -0,0 +1,5 @@
|
|||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import App from './App';
|
||||
|
||||
ReactDOM.render(<App />, document.getElementById('app'));
|
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"target": "esnext",
|
||||
"module": "commonjs",
|
||||
"jsx": "react",
|
||||
"declaration": true,
|
||||
"outDir": "./lib",
|
||||
"strict": true,
|
||||
"moduleResolution": "node",
|
||||
"esModuleInterop": true,
|
||||
"typeRoots": ["node_modules/@types", "node_modules/just-stack-react/node_modules/@types"]
|
||||
},
|
||||
|
||||
"include": ["src", "typings/*.d.ts"]
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
/// <reference types="node" />
|
||||
/// <reference types="react" />
|
||||
/// <reference types="react-dom" />
|
||||
|
||||
declare namespace NodeJS {
|
||||
interface ProcessEnv {
|
||||
readonly NODE_ENV: 'development' | 'production' | 'test';
|
||||
readonly PUBLIC_URL: string;
|
||||
}
|
||||
}
|
||||
|
||||
declare module '*.bmp' {
|
||||
const src: string;
|
||||
export default src;
|
||||
}
|
||||
|
||||
declare module '*.gif' {
|
||||
const src: string;
|
||||
export default src;
|
||||
}
|
||||
|
||||
declare module '*.jpg' {
|
||||
const src: string;
|
||||
export default src;
|
||||
}
|
||||
|
||||
declare module '*.jpeg' {
|
||||
const src: string;
|
||||
export default src;
|
||||
}
|
||||
|
||||
declare module '*.png' {
|
||||
const src: string;
|
||||
export default src;
|
||||
}
|
||||
|
||||
declare module '*.webp' {
|
||||
const src: string;
|
||||
export default src;
|
||||
}
|
||||
|
||||
declare module '*.svg' {
|
||||
import * as React from 'react';
|
||||
|
||||
export const ReactComponent: React.FunctionComponent<React.SVGProps<SVGSVGElement>>;
|
||||
|
||||
const src: string;
|
||||
export default src;
|
||||
}
|
||||
|
||||
declare module '*.module.css' {
|
||||
const classes: { [key: string]: string };
|
||||
export default classes;
|
||||
}
|
||||
|
||||
declare module '*.module.scss' {
|
||||
const classes: { [key: string]: string };
|
||||
export default classes;
|
||||
}
|
||||
|
||||
declare module '*.module.sass' {
|
||||
const classes: { [key: string]: string };
|
||||
export default classes;
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
const { webpackConfig, webpackMerge, htmlOverlay } = require('just-scripts');
|
||||
|
||||
module.exports = webpackMerge(
|
||||
webpackConfig,
|
||||
htmlOverlay({
|
||||
template: 'public/index.html'
|
||||
}),
|
||||
{
|
||||
// Here you can custom webpack configurations
|
||||
}
|
||||
);
|
|
@ -0,0 +1,13 @@
|
|||
const { webpackMerge, htmlOverlay, webpackServeConfig } = require('just-scripts');
|
||||
module.exports = webpackMerge(
|
||||
webpackServeConfig,
|
||||
htmlOverlay({
|
||||
template: 'public/index.html'
|
||||
}),
|
||||
{
|
||||
// Here you can custom webpack configurations
|
||||
output: {
|
||||
publicPath: '/'
|
||||
}
|
||||
}
|
||||
);
|
|
@ -0,0 +1,12 @@
|
|||
module.exports = function(plop) {
|
||||
plop.setGenerator('repo:just-stack-react', {
|
||||
actions: [
|
||||
{
|
||||
type: 'addMany',
|
||||
templateFiles: ['plop-templates/**/*.*', 'plop-templates/**/.*'],
|
||||
destination: '.',
|
||||
force: true
|
||||
}
|
||||
]
|
||||
});
|
||||
};
|
|
@ -1,5 +1,3 @@
|
|||
CHANGELOG.*
|
||||
*.log
|
||||
package-deps.json
|
||||
template.spec.js
|
||||
jest.config.js
|
||||
node_modules
|
|
@ -1 +0,0 @@
|
|||
module.exports = require('../../scripts/jest.template.config');
|
|
@ -1,34 +1,25 @@
|
|||
{
|
||||
"name": "just-stack-single-lib",
|
||||
"version": "0.8.7",
|
||||
"just-stack": true,
|
||||
"description": "Just stack for basic Node library",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/microsoft/just"
|
||||
},
|
||||
"main": "index.js",
|
||||
"keywords": [
|
||||
"just-stack"
|
||||
],
|
||||
"author": "",
|
||||
"license": "MIT",
|
||||
"main": "lib-commonjs/index.js",
|
||||
"module": "lib/index.js",
|
||||
"scripts": {
|
||||
"build": "npm test",
|
||||
"test": "jest"
|
||||
"build": "just-scripts build",
|
||||
"just": "just-scripts",
|
||||
"start": "just-scripts start",
|
||||
"test": "just-scripts test",
|
||||
"change": "beachball change"
|
||||
},
|
||||
"dependencies": {
|
||||
"fs-extra": "^7.0.1",
|
||||
"glob": "^7.1.3",
|
||||
"jest-expect-message": "^1.0.2",
|
||||
"json5": "^2.1.0",
|
||||
"just-scripts-utils": "^0.8.2",
|
||||
"@types/jest": "^24.0.0",
|
||||
"jest": "^24.0.0",
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.5.5",
|
||||
"@babel/preset-env": "^7.5.5",
|
||||
"@babel/preset-react": "^7.0.0",
|
||||
"@babel/preset-typescript": "^7.3.3",
|
||||
"@types/jest": "^24.0.16",
|
||||
"beachball": "^1.11.5",
|
||||
"jest": "^24.8.0",
|
||||
"just-scripts": "^0.26.0",
|
||||
"just-task": "^0.13.1",
|
||||
"ts-jest": "^24.0.1",
|
||||
"tslib": "^1.9.3",
|
||||
"typescript": "^3.2.4"
|
||||
"typescript": "^3.5.3"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
module.exports = {
|
||||
presets: ['@babel/preset-env', '@babel/preset-typescript', '@babel/preset-react']
|
||||
};
|
|
@ -0,0 +1,4 @@
|
|||
node_modules
|
||||
lib
|
||||
lib-commonjs
|
||||
dist
|
|
@ -0,0 +1,5 @@
|
|||
module.exports = {
|
||||
clearMocks: true,
|
||||
testEnvironment: 'node',
|
||||
testMatch: ['<rootDir>/src/**/__tests__/**/*.[jt]s?(x)', '<rootDir>/src/**/?(*.)+(spec|test).[tj]s?(x)']
|
||||
};
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче