Skip to content

Commit

Permalink
fixup types in webpack.configs
Browse files Browse the repository at this point in the history
  • Loading branch information
DanDroryAu committed Dec 17, 2024
2 parents 6469c14 + f47797f commit becabc3
Show file tree
Hide file tree
Showing 32 changed files with 278 additions and 226 deletions.
2 changes: 1 addition & 1 deletion fixtures/ssr-hello-world/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
.eslintcache
.prettierrc
coverage/
dist-start/
dist-build/
eslint.config.mjs
report/
tsconfig.json
Expand Down
2 changes: 1 addition & 1 deletion fixtures/ssr-hello-world/.prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
.eslintcache
.prettierrc
coverage/
dist-start/
dist-build/
eslint.config.mjs
pnpm-lock.yaml
report/
Expand Down
3 changes: 2 additions & 1 deletion packages/sku/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
"type": "module",
"scripts": {
"postinstall": "node ./scripts/postinstall.js",
"build": "tsc",
"build": "tsc --project tsconfig.build.json",
"lint:tsc": "tsc --noEmit"
},
"repository": {
Expand Down Expand Up @@ -161,6 +161,7 @@
},
"devDependencies": {
"@jest/globals": "^29.7.0",
"@types/babel__core": "^7.20.5",
"@types/cross-spawn": "^6.0.3",
"@types/death": "^1.1.5",
"@types/debug": "^4.1.12",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,19 @@
import { cwd } from '../../lib/cwd.js';
import { createRequire } from 'node:module';
import type { PluginItem } from '@babel/core';

const require = createRequire(import.meta.url);

type BabelConfigOptions = {
target: 'node' | 'browser' | 'jest';
lang: 'js' | 'ts';
browserslist?: string[];
displayNamesProd?: boolean;
removeAssertionsInProduction?: boolean;
hot?: boolean;
rootResolution?: boolean;
};

export default ({
target,
lang = 'js',
Expand All @@ -11,12 +22,12 @@ export default ({
removeAssertionsInProduction = true,
hot = false,
rootResolution = false,
}) => {
}: BabelConfigOptions) => {
const isBrowser = target === 'browser';
const isJest = target === 'jest';
const isProductionBuild = process.env.NODE_ENV === 'production';

const plugins = [
const plugins: PluginItem[] = [
[
require.resolve('babel-plugin-module-resolver'),
{
Expand Down
15 changes: 8 additions & 7 deletions packages/sku/src/config/typescript/tsconfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,15 +39,16 @@ export default () => {
jsx: 'react-jsx',
lib: ['dom', 'dom.iterable', 'es2022'],
target: 'es2022',
...(rootResolution
? {
paths: {
'*': ['*'],
},
baseUrl: cwd(),
}
: {}),
},
};

if (rootResolution) {
config.compilerOptions.paths = {
'*': ['*'],
};
config.compilerOptions.baseUrl = cwd();
}

return tsconfigDecorator(config);
};
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import isCI from '../../lib/isCI.js';

const disableCacheOverride = Boolean(process.env.SKU_DISABLE_CACHE);

function getWebpackCacheSettings({ isDevServer }) {
function getWebpackCacheSettings({ isDevServer }: { isDevServer: boolean }) {
if (isDevServer && !isCI && !disableCacheOverride) {
return {
type: 'filesystem',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
transformOutputPath,
publicPath,
} from '../../../context/index.js';
import type { Stats } from 'webpack';

// @ts-expect-error
const { default: memoize } = nanoMemoize;
Expand All @@ -28,7 +29,7 @@ const getCachedClientStats = memoize(getClientStats);

// mapStatsToParams runs once for each render. It's purpose is
// to forward the client webpack stats to the render function
const mapStatsToParams = ({ webpackStats }) => {
const mapStatsToParams = ({ webpackStats }: { webpackStats: Stats }) => {
const stats = getCachedClientStats(webpackStats);

return {
Expand All @@ -49,7 +50,7 @@ const getStartRoutes = () => {
if (routeIsForSpecificSite) {
allRouteCombinations.push({
route,
site: sites[route.siteIndex],
site: sites[route.siteIndex!],
language,
});
} else {
Expand Down Expand Up @@ -83,7 +84,7 @@ const getBuildRoutes = () => {
if (routeIsForSpecificSite) {
allRouteCombinations.push({
route,
site: sites[route.siteIndex],
site: sites[route.siteIndex!],
environment,
language,
});
Expand Down Expand Up @@ -121,6 +122,11 @@ const createHtmlRenderPlugin = () => {
renderDirectory: paths.target,
routes: allRoutes,
skipAssets: isStartScript,
// Incompatible type here. In the SkuConfig type the `transformOutputPath` input is the following type:
// environment: string;
// site: string;
// path: string; Path does not exist in the transformFilePath type that the HTMLRenderPLugin accepts.
// @ts-expect-error
transformFilePath: transformOutputPath,
mapStatsToParams,
extraGlobals: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,26 @@ import { performance } from 'node:perf_hooks';
import prettyMilliseconds from 'pretty-ms';
import debug from 'debug';
import provider from '../../../../telemetry/index.js';
import type { Compiler, WebpackPluginInstance } from 'webpack';

const log = debug('sku:metrics');

const smp = 'sku-metrics-plugin';

class MetricsPlugin {
constructor({ type, target }) {
class MetricsPlugin implements WebpackPluginInstance {
private initial: boolean;
private readonly target: string;
private readonly type: string;
private startTime: number;

constructor({ type, target }: { type: string; target: string }) {
this.initial = true;
this.target = target;
this.type = type;
this.startTime = 0;
}

apply(compiler) {
apply(compiler: Compiler) {
compiler.hooks.watchRun.tap(smp, () => {
this.startTime = performance.now();
});
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import webpack from 'webpack';
import webpack, { type Compiler, type WebpackPluginInstance } from 'webpack';
import defaultSupportedBrowsers from 'browserslist-config-seek';
import { VanillaExtractPlugin } from '@vanilla-extract/webpack-plugin';
import {
Expand All @@ -12,32 +12,42 @@ import {
resolvePackage,
} from '../../utils/index.js';
import defaultCompilePackages from '../../../../context/defaultCompilePackages.js';
import validateOptions from './validateOptions.js';
import validateOptions, {
type SkuWebpackPluginOptions,
} from './validateOptions.js';
import targets from '../../../targets.json' with { type: 'json' };

class SkuWebpackPlugin {
constructor(options = {}) {
class SkuWebpackPlugin implements WebpackPluginInstance {
options: SkuWebpackPluginOptions;
compilePackages: string[];
include: string[];

constructor(options: SkuWebpackPluginOptions) {
validateOptions(options);

this.options = {
// Is this default value correct? I imagine it will be set via the options.
include: [],
hot: false,
generateCSSTypes: false,
browserslist: defaultSupportedBrowsers,
browserslist: defaultSupportedBrowsers as unknown as string[],
compilePackages: [],
rootResolution: false,
...options,
};
this.compilePackages = [
...new Set([...defaultCompilePackages, ...this.options.compilePackages]),
...new Set([
...defaultCompilePackages,
...(this.options.compilePackages || []),
]),
];
this.include = [
...this.options.include,
...(this.options.include || []),
...this.compilePackages.map(resolvePackage),
];
}

apply(compiler) {
apply(compiler: Compiler) {
const {
target,
hot,
Expand Down Expand Up @@ -121,6 +131,7 @@ class SkuWebpackPlugin {
// more standard handling of include/exclude path matching.
exclude: /node_modules\/playroom/,
use: makeExternalCssLoaders({
target,
isProductionBuild,
MiniCssExtractPlugin,
hot,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@ import Validator from 'fastest-validator';
import browserslist from 'browserslist';
import chalk from 'chalk';
import didYouMean from 'didyoumean2';
import { hasErrorMessage } from '../../../../lib/utils/error-guards.js';

// @ts-expect-error
const validator = new Validator();

const exitWithErrors = async (errors) => {
const exitWithErrors = async (errors: string[]) => {
console.log(
chalk.bold(chalk.underline(chalk.red('SkuWebpackPlugin: Invalid options'))),
);
Expand All @@ -15,6 +17,21 @@ const exitWithErrors = async (errors) => {
process.exit(1);
};

export type SkuWebpackPluginOptions = {
target: 'node' | 'browser';
MiniCssExtractPlugin: any;
mode?: 'development' | 'production';
hot?: boolean;
include?: string[];
compilePackages?: string[];
libraryName?: string;
generateCSSTypes?: boolean;
removeAssertionsInProduction?: boolean;
browserslist?: string[];
displayNamesProd?: boolean;
rootResolution?: boolean;
};

const schema = {
target: {
type: 'enum',
Expand Down Expand Up @@ -73,7 +90,7 @@ const validate = validator.compile(schema);

const availableOptions = Object.keys(schema);

const validateOptions = (options) => {
const validateOptions = (options: SkuWebpackPluginOptions) => {
const errors = [];

// Validate extra keys
Expand All @@ -91,25 +108,29 @@ const validateOptions = (options) => {
// Validate schema types
const schemaCheckResult = validate(options);
if (schemaCheckResult !== true) {
schemaCheckResult.forEach(({ message, field }) => {
const errorMessage = message
? `🚫 ${message.replace(field, `${chalk.bold(field)}`)}`
: `🚫 '${chalk.bold(field)}' is invalid`;
schemaCheckResult.forEach(
({ message, field }: { message: string; field: string }) => {
const errorMessage = message
? `🚫 ${message.replace(field, `${chalk.bold(field)}`)}`
: `🚫 '${chalk.bold(field)}' is invalid`;

errors.push(errorMessage);
});
errors.push(errorMessage);
},
);
}

if (options.browserslist) {
// Ensure 'browserslist' is valid browserslist query
try {
browserslist(options.browserslist);
} catch (e) {
errors.push(
`🚫 '${chalk.bold(
'browserslist',
)}' must be a valid browserslist query. ${chalk.white(e.message)}`,
);
if (hasErrorMessage(e)) {
errors.push(
`🚫 '${chalk.bold(
'browserslist',
)}' must be a valid browserslist query. ${chalk.white(e.message)}`,
);
}
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import { join } from 'node:path';
import { fileURLToPath } from 'node:url';
import { createRequire } from 'node:module';

const require = createRequire(import.meta.url);

const modules = ['node_modules'];

try {
const skuPath = fileURLToPath(import.meta.resolve('sku/package.json'));
const skuPath = require.resolve('sku/package.json');

// If the project is using pnpm then we add the sku node_modules directory
// to the modules array. This allows dependecies of sku to be importable
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { sourceMapsProd } from '../../context/index.js';

function getSourceMapSetting({ isDevServer }) {
function getSourceMapSetting({ isDevServer }: { isDevServer: boolean }) {
if (isDevServer) {
return 'eval-cheap-module-source-map';
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
// @ts-check
import isCI from '../../lib/isCI.js';

/**
* @param {object} [options]
* @param {string} [options.stats]
* @param {boolean} [options.isStartScript]
*/
const getStatsConfig = ({ stats, isStartScript = false } = {}) => {
const getStatsConfig = ({
stats,
isStartScript = false,
}: { stats?: string; isStartScript?: boolean } = {}) => {
const defaultPreset = isStartScript ? 'summary' : 'errors-only';

return {
Expand Down
11 changes: 11 additions & 0 deletions packages/sku/src/config/webpack/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
export interface MakeWebpackConfigOptions {
isIntegration?: boolean;
isDevServer?: boolean;
metrics?: boolean;
htmlRenderPlugin?: any;
hot?: boolean;
isStartScript?: boolean;
stats?: string;
clientPort?: number;
serverPort?: number;
}
Loading

0 comments on commit becabc3

Please sign in to comment.