Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions packages/just-scripts/etc/just-scripts.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -469,9 +469,6 @@ export interface TsOverlayOptions {
// @public (undocumented)
function webapp(): void;

// @public
export function webpackCliInitTask(customScaffold?: string, auto?: boolean): TaskFunction;

// @public
export function webpackCliTask(options?: WebpackCliTaskOptions): TaskFunction;

Expand Down
116 changes: 114 additions & 2 deletions packages/just-scripts/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,127 @@
"supports-color": "^8.1.0",
"webpack-merge": "^5.7.3"
},
"peerDependencies": {
"@microsoft/api-extractor": "^7.0.0",
"@microsoft/loader-load-themed-styles": "^1.0.0 || ^2.0.0",
"autoprefixer": "^10.0.0",
"css-loader": "^5.0.0 || ^6.0.0 || ^7.0.0",
"esbuild": ">=0.8.0",
"eslint": "^7.0.0 || ^8.0.0 || ^9.0.0 || ^10.0.0",
"fork-ts-checker-webpack-plugin": "^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0",
"html-webpack-plugin": "^4.0.0 || ^5.0.0",
"jest": "^26.0.0 || ^27.0.0 || ^28.0.0 || ^29.0.0 || ^30.0.0",
"node-sass": "^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0",
"postcss": "^8.0.0",
"postcss-clean": "^1.0.0",
"postcss-loader": "^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0",
"postcss-rtl": "^1.0.0 || ^2.0.0",
"prettier": "^2.0.0 || ^3.0.0",
"sass": "^1.0.0",
"sass-loader": "^10.0.0 || ^11.0.0 || ^12.0.0 || ^13.0.0 || ^14.0.0 || ^15.0.0 || ^16.0.0",
"style-loader": "^2.0.0 || ^3.0.0 || ^4.0.0",
"tar-fs": "^2.0.0 || ^3.0.0",
"tslint": "^6.0.0",
"tslint-microsoft-contrib": "^6.0.0",
"typescript": "^4.0.0 || ^5.0.0 || ^6.0.0",
"webpack": "^4.0.0 || ^5.0.0",
"webpack-cli": "^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0",
"webpack-dev-server": "^3.0.0 || ^4.0.0 || ^5.0.0"
},
"peerDependenciesMeta": {
"@microsoft/api-extractor": {
"optional": true
},
"@microsoft/loader-load-themed-styles": {
"optional": true
},
"autoprefixer": {
"optional": true
},
"css-loader": {
"optional": true
},
"esbuild": {
"optional": true
},
"eslint": {
"optional": true
},
"fork-ts-checker-webpack-plugin": {
"optional": true
},
"html-webpack-plugin": {
"optional": true
},
"jest": {
"optional": true
},
"node-sass": {
"optional": true
},
"postcss": {
"optional": true
},
"postcss-clean": {
"optional": true
},
"postcss-loader": {
"optional": true
},
"postcss-rtl": {
"optional": true
},
"prettier": {
"optional": true
},
"sass": {
"optional": true
},
"sass-loader": {
"optional": true
},
"style-loader": {
"optional": true
},
"tar-fs": {
"optional": true
},
"tslint": {
"optional": true
},
"tslint-microsoft-contrib": {
"optional": true
},
"typescript": {
"optional": true
},
"webpack": {
"optional": true
},
"webpack-cli": {
"optional": true
},
"webpack-dev-server": {
"optional": true
}
},
"devDependencies": {
"@microsoft/api-extractor": "^7.57.7",
"@types/cross-spawn": "^6.0.6",
"@types/diff-match-patch": "^1.0.32",
"@types/glob": "^7.2.0",
"@types/prompts": "^2.4.2",
"@types/run-parallel-limit": "^1.0.0",
"@types/supports-color": "^8.1.1",
"@types/webpack": "^4.41.33",
"@types/tar-fs": "^2.0.4",
"async-done": "^2.0.0",
"esbuild": "^0.9.6"
"autoprefixer": "^10.4.27",
"esbuild": "^0.27.4",
"fork-ts-checker-webpack-plugin": "^9.1.0",
"html-webpack-plugin": "^5.6.6",
"postcss": "^8.5.8",
"postcss-clean": "^1.2.2",
"sass": "^1.98.0",
"webpack": "^5.105.4"
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import * as mockfs from 'mock-fs';
import mockfs from 'mock-fs';
import * as path from 'path';
import * as fs from 'fs';
// import { dirSync, fileSync, DirResult, FileResult } from 'tmp';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import * as asyncDoneAsCallback from 'async-done';
import asyncDoneAsCallback from 'async-done';
import { promisify } from 'util';
import type { Arguments } from 'yargs-parser';
import { logger, TaskFunction, TaskContext } from 'just-task';
Expand Down
8 changes: 5 additions & 3 deletions packages/just-scripts/src/tasks/__tests__/tscTask.spec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
import * as mockfs from 'mock-fs';
import { spawn } from '../../utils';
import { tscTask, tscWatchTask } from '../tscTask';
import mockfs from 'mock-fs';
import { callTaskForTest } from './callTaskForTest';
import { getNormalizedSpawnArgs } from './getNormalizedSpawnArgs';

Expand All @@ -16,6 +14,10 @@ jest.mock('../../utils/exec', () => {
});
jest.mock('just-task/lib/logger');

// Must be imported after jest.mock() calls for the mocks to take effect
import { spawn } from '../../utils';
import { tscTask, tscWatchTask } from '../tscTask';

const mockSpawn = spawn as jest.MockedFunction<typeof spawn>;

/**
Expand Down
2 changes: 1 addition & 1 deletion packages/just-scripts/src/tasks/apiExtractorTask.ts
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ export function apiExtractorUpdateTask(
* Returns undefined if api-extractor or the config file couldn't be found.
*/
function initApiExtractor(options: ApiExtractorOptions): ApiExtractorContext | undefined {
const apiExtractorModule: typeof ApiExtractorTypes = tryRequire('@microsoft/api-extractor');
const apiExtractorModule = tryRequire<typeof ApiExtractorTypes>('@microsoft/api-extractor');

if (!apiExtractorModule) {
logger.warn('@microsoft/api-extractor package not detected. This task will have no effect.');
Expand Down
2 changes: 1 addition & 1 deletion packages/just-scripts/src/tasks/cleanTask.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import * as fse from 'fs-extra';
import * as path from 'path';
import { logger, TaskFunction, clearCache } from 'just-task';
import parallelLimit = require('run-parallel-limit');
import parallelLimit from 'run-parallel-limit';

export interface CleanTaskOptions {
/**
Expand Down
2 changes: 1 addition & 1 deletion packages/just-scripts/src/tasks/copyTask.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import * as glob from 'glob';
import * as fse from 'fs-extra';
import * as path from 'path';
import { logger, TaskFunction } from 'just-task';
import parallelLimit = require('run-parallel-limit');
import parallelLimit from 'run-parallel-limit';

export interface CopyTaskOptions {
/** Paths to copy */
Expand Down
1 change: 0 additions & 1 deletion packages/just-scripts/src/tasks/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ export * from './apiExtractorTask';
export * from './copyInstructionsTask';
export * from './prettierTask';
export * from './eslintTask';
export * from './webpackCliInitTask';
export * from './webpackCliTask';
export * from './webpackDevServerTask';
export * from './tarTask';
Expand Down
2 changes: 1 addition & 1 deletion packages/just-scripts/src/tasks/jestTask.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { resolve, logger, resolveCwd, TaskFunction, argv } from 'just-task';
import { spawn, readPackageJson, logNodeCommand } from '../utils';
import { existsSync } from 'fs';
import * as supportsColor from 'supports-color';
import supportsColor from 'supports-color';

export interface JestTaskOptions {
config?: string;
Expand Down
12 changes: 6 additions & 6 deletions packages/just-scripts/src/tasks/sassTask.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import * as fs from 'fs';
import { resolveCwd, TaskFunction, logger } from 'just-task';
import { tryRequire } from '../tryRequire';
import parallelLimit = require('run-parallel-limit');
import parallelLimit from 'run-parallel-limit';

export interface SassTaskOptions {
createSourceModule: (fileName: string, css: string) => string;
Expand Down Expand Up @@ -31,9 +31,9 @@
postcssPlugins = postcssPlugins || [];

return function sass(done: (err?: Error) => void) {
const sass = tryRequire('sass') || tryRequire('node-sass');
const postcss = tryRequire('postcss');
const autoprefixer = tryRequire('autoprefixer');
const sass = tryRequire<typeof import('sass')>('sass') || tryRequire<typeof import('sass')>('node-sass');
const postcss = tryRequire<typeof import('postcss')>('postcss');
const autoprefixer = tryRequire<typeof import('autoprefixer')>('autoprefixer');
const postcssRtl = tryRequire('postcss-rtl');
const clean = tryRequire('postcss-clean');

Expand All @@ -59,11 +59,11 @@
importer: patchSassUrl,
includePaths: [path.resolve(process.cwd(), 'node_modules')],
},
(err: Error, result: { css: Buffer }) => {
(err: import('sass').LegacyException | undefined, result: import('sass').LegacyResult | undefined) => {
if (err) {
cb(path.relative(process.cwd(), fileName) + ': ' + err);
} else {
const css = result.css.toString();
const css = result!.css.toString();

Check warning on line 66 in packages/just-scripts/src/tasks/sassTask.ts

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest)

Forbidden non-null assertion

// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const plugins = [autoprefixerFn, ...postcssPlugins!];
Expand Down
41 changes: 0 additions & 41 deletions packages/just-scripts/src/tasks/webpackCliInitTask.ts

This file was deleted.

16 changes: 8 additions & 8 deletions packages/just-scripts/src/tasks/webpackTask.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@

export function webpackTask(options?: WebpackTaskOptions): TaskFunction {
return async function webpack() {
const wp: typeof import('webpack') = tryRequire('webpack');
const wp = tryRequire<typeof import('webpack')>('webpack');

if (!wp) {
logger.warn('webpack is not installed, this task no effect');
Expand Down Expand Up @@ -80,23 +80,23 @@
webpackConfigs = webpackConfigPromises.map(webpackConfig => merge(webpackConfig, restConfig));

return new Promise<void>((resolve, reject) => {
wp(webpackConfigs, async (err: Error, stats: any) => {
wp(webpackConfigs, async (err, stats) => {
if (options && options.onCompile) {
await options.onCompile(err, stats);
await options.onCompile(err as Error, stats);
}

if (options && options.outputStats) {
const statsFile = options.outputStats === true ? 'stats.json' : options.outputStats;
fs.writeFileSync(statsFile, JSON.stringify(stats.toJson(), null, 2));
fs.writeFileSync(statsFile, JSON.stringify(stats!.toJson(), null, 2));

Check warning on line 90 in packages/just-scripts/src/tasks/webpackTask.ts

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest)

Forbidden non-null assertion
}

if (err || stats.hasErrors()) {
if (err || stats?.hasErrors()) {
// Stats may be undefined the the case of an error in Webpack 5
if (stats) {
logger.error(stats.toString({ children: webpackConfigs.map(c => c.stats) }));
reject(`Webpack failed with ${stats.toJson('errors-only').errors.length} error(s).`);
logger.error(stats.toString({ children: webpackConfigs.map(c => c.stats).filter(Boolean) as any }));
reject(`Webpack failed with ${stats.toJson('errors-only').errors!.length} error(s).`);

Check warning on line 97 in packages/just-scripts/src/tasks/webpackTask.ts

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest)

Forbidden non-null assertion
} else {
logger.error(err.toString());
logger.error(err!.toString());

Check warning on line 99 in packages/just-scripts/src/tasks/webpackTask.ts

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest)

Forbidden non-null assertion
reject(`Webpack failed with error(s).`);
}
} else {
Expand Down
4 changes: 2 additions & 2 deletions packages/just-scripts/src/tryRequire.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { resolve } from 'just-task';

export function tryRequire(specifier: string): any {
export function tryRequire<T = any>(specifier: string): T | null {
const resolved = resolve(specifier);

if (!resolved) {
return null;
}

let requiredModule = null;
let requiredModule: T | null = null;

try {
requiredModule = require(resolved);
Expand Down
20 changes: 14 additions & 6 deletions packages/just-scripts/src/utils/__tests__/exec.spec.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,20 @@
import * as cp from 'child_process';
import type * as cp from 'child_process';
import * as path from 'path';
import { encodeArgs, spawn } from '../exec';
import { getMockScript } from '../../__tests__/getMockScript';
import { MockOutputStream } from '../../__tests__/MockOutputStream';
import { fail } from 'assert';

// Mock child_process so we can spy on spawn calls from cross-spawn
const realCp = jest.requireActual<typeof cp>('child_process');
const cpSpawnMock = jest.fn((...args: Parameters<typeof cp.spawn>) => realCp.spawn(...args)) as jest.Mock &
typeof cp.spawn;
jest.mock('child_process', () => {
const original = jest.requireActual<typeof cp>('child_process');
return { ...original, spawn: cpSpawnMock };
});

import { encodeArgs, spawn } from '../exec';

describe('encodeArgs', () => {
it('encodes things with spaces with double quotes', () => {
const args = encodeArgs(['blah blah']);
Expand All @@ -18,10 +28,8 @@ describe('encodeArgs', () => {
});

describe('spawn', () => {
const spawnSpy = jest.spyOn(cp, 'spawn');

afterEach(() => {
spawnSpy.mockClear();
cpSpawnMock.mockClear();
});

it('handles success case', async () => {
Expand Down Expand Up @@ -55,7 +63,7 @@ describe('spawn', () => {
// TODO: in newer node, also test with spawn's signal option
it('handles signal', async () => {
const promise = spawn(process.execPath, [getMockScript('mock-forever.js')]);
const child = spawnSpy.mock.results[0].value as cp.ChildProcess;
const child = cpSpawnMock.mock.results[0].value as cp.ChildProcess;
expect(child).toBeTruthy();
try {
child.kill('SIGTERM');
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { readPackageJson } from '../readPackageJson';
import * as mockfs from 'mock-fs';
import mockfs from 'mock-fs';

describe('readPackageJson', () => {
const testDir = 'testDir';
Expand Down
Loading
Loading