Skip to content

Commit

Permalink
feat: rework and tuneup
Browse files Browse the repository at this point in the history
  • Loading branch information
seebeen committed Jun 18, 2024
1 parent 377cdfe commit fb34a79
Show file tree
Hide file tree
Showing 30 changed files with 519 additions and 214 deletions.
4 changes: 4 additions & 0 deletions dump
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@

> @x-wp/wordpack@0.0.0-development test
> webpack --config test/webpack.config.ts --env basePath=./test

22 changes: 17 additions & 5 deletions lib/config/bundle.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
ValidateIf,
} from 'class-validator';
import type { Configuration } from 'webpack';
import * as path from 'node:path';

export class BundleConfig {
@IsString()
Expand All @@ -21,8 +22,7 @@ export class BundleConfig {
files!: string[];

@IsBoolean()
@IsOptional()
splitChunks: boolean = false;
splitChunks: boolean = true;

@IsOptional()
@IsInstance(RegExp)
Expand All @@ -35,12 +35,11 @@ export class BundleConfig {
@IsOptional()
chunkId: string = 'vendor-[name]';

@Min(20000)
@Min(10)
@IsPositive()
@IsInt()
@IsOptional()
@ValidateIf((o: BundleConfig) => o.splitChunks === true)
chunkMinSize: number = 20000;
chunkMinSize: number = 5000;

@IsHexColor()
@IsOptional()
Expand All @@ -61,4 +60,17 @@ export class BundleConfig {
get chunkName(): string {
return this.chunkId.replace('[name]', this.name);
}

get entry(): Record<string, string[]> {
return this.files.reduce(
(obj, file) => {
const base = path.basename(file, path.extname(file));
obj[base] ??= [];
obj[base].push(file);

return obj;
},
{} as Record<string, string[]>,
);
}
}
19 changes: 19 additions & 0 deletions lib/config/dir.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { Allow, IsNotEmpty, IsOptional, IsString } from 'class-validator';

export class DirMap {
src: string;
dist: string;
}

export class PathConfig {
@Allow()
root: DirMap | string = { src: 'assets', dist: 'dist' };
@Allow()
scripts: DirMap | string = 'scripts';
@Allow()
styles: DirMap | string = 'styles';
@Allow()
images: DirMap | string = 'images';
@Allow()
fonts: DirMap | string = 'fonts';
}
145 changes: 80 additions & 65 deletions lib/config/wordpack.config.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
import { Configuration } from 'webpack';
import { Expose, Transform, Type } from 'class-transformer';
import {
Configuration,
ExternalItemFunctionData,
ExternalItemObjectKnown,
ExternalItemObjectUnknown,
ExternalItemValue,
} from 'webpack';
import { Transform, Type } from 'class-transformer';
import {
IsBoolean,
IsEnum,
Expand All @@ -11,67 +17,72 @@ import {
} from 'class-validator';
import { WordPackEnv } from './wordpack-env';
import { BundleConfig } from './bundle.config';
import { DirMap, PathConfig } from './dir.config';

type ExternalItem =
| string
| RegExp
| (ExternalItemObjectKnown & ExternalItemObjectUnknown)
| ((
data: ExternalItemFunctionData,
callback: (
err?: null | Error,
result?: string | boolean | string[] | { [index: string]: any },
) => void,
) => void)
| ((data: ExternalItemFunctionData) => Promise<ExternalItemValue>);

type DirType = keyof DirMap;

export class WordPackConfig extends WordPackEnv {
@IsString()
@Transform(({ value }) =>
(value || '[name].[contenthash:6][ext]').replace('[ext]', ''),
)
@IsOptional()
@Expose()
filename: string;
@Transform(({ value }) => value.replace('[ext]', ''))
filename: string = '[name].[contenthash:6]';

@IsString()
@IsOptional()
manifest: string = 'assets.json';

@ValidateNested({ each: true })
@Type(() => BundleConfig)
bundles!: BundleConfig[];

@IsObject()
@IsOptional()
@IsOptional()
externals: Record<string, string> = {
jquery: 'jQuery',
underscore: '_',
backbone: 'backbone',
};
@IsNotEmpty()
externals:
| string
| RegExp
| ExternalItem[]
| (ExternalItemObjectKnown & ExternalItemObjectUnknown)
| ((
data: ExternalItemFunctionData,
callback: (
err?: null | Error,
result?: string | boolean | string[] | { [index: string]: any },
) => void,
) => void)
| ((data: ExternalItemFunctionData) => Promise<ExternalItemValue>) = [
{
jquery: 'jQuery',
underscore: '_',
backbone: 'backbone',
lodash: '_',
},
// function ({ context, request }, callback) {
// if (/^lodash/.test(request as string)) {
// callback(null, 'window _');
// return;
// }
// callback();
// },
];

@IsBoolean()
@IsOptional()
@IsOptional()
multimode: boolean = true;

@IsString()
@IsNotEmpty()
@IsOptional()
srcBase?: string = 'assets';

@IsString()
@IsNotEmpty()
@IsOptional()
distBase?: string = 'dist';

@IsString()
@IsNotEmpty()
@IsOptional()
imageDir?: string = 'images';

@IsString()
@IsNotEmpty()
@IsOptional()
fontDir?: string = 'fonts';

@IsString()
@IsNotEmpty()
@IsOptional()
jsDir?: string = 'scripts';

@IsString()
@IsNotEmpty()
@IsOptional()
cssDir?: string = 'styles';
@IsObject()
@ValidateNested()
@Type(() => PathConfig)
paths: PathConfig = new PathConfig();

@IsEnum([
'eval',
Expand All @@ -86,35 +97,43 @@ export class WordPackConfig extends WordPackEnv {
sourceMaps: string | false = 'eval-cheap-source-map';

@IsString({ each: true })
@IsOptional()
globalChunks: string[] = ['awesome-notifications'];

@IsObject()
@IsOptional()
override: Partial<Configuration> = {};

get srcDir(): string {
return this.srcBase as string;
root(which: DirType): string {
return this.dir(which, 'root');
}

get distRoot(): string {
return this.distBase as string;
images(which: DirType): string {
return this.dir(which, 'images');
}

get images(): string {
return this.imageDir as string;
scripts(which: DirType): string {
return this.dir(which, 'scripts');
}

get fonts(): string {
return this.fontDir as string;
styles(which: DirType): string {
return this.dir(which, 'styles');
}

get scripts(): string {
return this.jsDir as string;
fonts(which: DirType): string {
return this.dir(which, 'fonts');
}

get styles(): string {
return this.cssDir as string;
path(which: DirType, dir: keyof PathConfig): string {
return dir === 'root'
? this.resolve(this.dir(which, 'root'))
: this.resolve(this.dir(which, 'root'), this.dir(which, dir));
}

dir(which: DirType, dir: keyof PathConfig): string {
if (typeof this.paths[dir] === 'string') {
return this.paths[dir] as string;
}

return this.paths[dir][which];
}

get mode(): 'production' | 'development' {
Expand All @@ -128,8 +147,4 @@ export class WordPackConfig extends WordPackEnv {
get isCI(): boolean {
return process.env.CI !== undefined;
}

get distPath(): string {
return this.resolve(this.distRoot);
}
}
5 changes: 4 additions & 1 deletion lib/functions/build-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,12 @@ export async function buildConfig(
),
);

// console.log(res);
// process.exit(0);

res.push(Svc.AssetConfig.build(cfg));

fs.emptyDirSync(cfg.distPath);
fs.emptyDirSync(cfg.path('dist', 'root'));

return res;
} catch (e) {
Expand Down
12 changes: 3 additions & 9 deletions lib/functions/manifest-utils.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,10 @@
import WebpackAssetsManifest, { Entry } from 'webpack-assets-manifest';
import * as path from 'node:path';
import * as fs from 'fs-extra';
import { Asset } from 'webpack';

export function manifestEntryFormatter({ key, value }: Entry): Entry | false {
const base = (p: string) => path.basename(path.dirname(p));

const src = base(key);
const dst = base(value);

if (src !== dst) {
key = `${dst}/${key}`;
}
key = `${path.dirname(value)}/${path.basename(key)}`;

return { key, value };
}
Expand All @@ -31,7 +25,7 @@ return array(
{{{entries}}}
);
`;
const assets = Object.keys(mfs.assets);
const assets = Object.keys(mfs.assets).sort();
const length = findLongest(assets);
const entries = assets.map((k) => parseEntry(k, mfs.assets[k], length));

Expand Down
1 change: 1 addition & 0 deletions lib/interfaces/bundle-config.interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,5 @@ export interface BundleConfigInterface {
globalChunks?: string[];
override?: Partial<Configuration>;
color?: string;
entry?: Record<string, string[]>;
}
9 changes: 3 additions & 6 deletions lib/interfaces/wordpack-config.interface.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,13 @@
import { PathConfig } from '../config/dir.config';
import { BundleConfigInterface } from './bundle-config.interface';

export interface WordPackConfigInterface {
paths?: Partial<PathConfig>;
manifest?: string;
filename?: string;
bundles: BundleConfigInterface[];
multimode?: boolean;
externals?: Record<string, string>;
srcBase?: string;
distBase?: string;
imageDir?: string;
fontDir?: string;
jsDir?: string;
cssDir?: string;

sourceMaps?: string | false;
}
25 changes: 17 additions & 8 deletions lib/services/asset-config.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,23 +20,23 @@ export class AssetConfig {
private static getCoreConfig(cfg: WordPackConfig): Configuration {
return {
name: 'AssetCopy',
context: cfg.resolve(cfg.srcDir),
context: cfg.path('src', 'root'),
mode: cfg.mode,
entry: {},
output: {
path: cfg.resolve(cfg.distRoot),
path: cfg.path('dist', 'root'),
},
stats: false,
plugins: [
new CopyPlugin({
patterns: [
{
from: `${cfg.images}/**/*`,
to: `[path]${cfg.asset}[ext]`,
from: `${cfg.images('src')}/`,
to: `${cfg.images('dist')}/[path][name][ext]`,
force: false,
noErrorOnMissing: true,
filter: (rp) =>
!fs.existsSync(rp.replace(cfg.srcDir, cfg.distRoot)),
noErrorOnMissing: false,
toType: 'template',
filter: (rp) => this.filterAssets(cfg, rp),
},
],
}),
Expand All @@ -50,6 +50,14 @@ export class AssetConfig {
};
}

static filterAssets(cfg: WordPackConfig, rp: string): boolean {
return !fs.existsSync(
rp
.replace(cfg.root('src'), cfg.root('dist'))
.replace(cfg.images('src'), cfg.images('dist')),
);
}

private static getOptimizeConfig(cfg: WordPackConfig): Configuration {
if (!cfg.prod) {
return {};
Expand All @@ -62,8 +70,9 @@ export class AssetConfig {
},
};
}

private static getManifestConfig(cfg: WordPackConfig): Configuration {
if (!cfg.prod || !cfg.manifest) {
if (!cfg.manifest) {
return {};
}
return {
Expand Down
Loading

0 comments on commit fb34a79

Please sign in to comment.