Skip to content

Commit

Permalink
feat(vite): 新增读取构建插件
Browse files Browse the repository at this point in the history
  • Loading branch information
KonghaYao committed Jun 2, 2024
1 parent ee354ee commit aca88c6
Show file tree
Hide file tree
Showing 8 changed files with 145 additions and 46 deletions.
5 changes: 3 additions & 2 deletions packages/vite/package.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"version": "0.7.2",
"version": "0.8.0",
"name": "vite-plugin-font",
"description": "auto CJK font subset for Vite and Nuxt",
"main": "./dist/vite.js",
Expand Down Expand Up @@ -47,7 +47,8 @@
"vite": "^5"
},
"dependencies": {
"@konghayao/cn-font-split": "workspace:^"
"@konghayao/cn-font-split": "workspace:^",
"glob": "^10.4.1"
},
"bugs": {
"url": "https://github.com/KonghaYao/cn-font-split/issues"
Expand Down
14 changes: 10 additions & 4 deletions packages/vite/src/font.d.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,20 @@

declare module '@konghayao/_font_' {
import { fontSplit } from '@konghayao/cn-font-split';
type Reporter = Awaited<ReturnType<typeof fontSplit>>;
export const css: Reporter['css'];
}

declare module '*.ttf' {
export * from '@konghayao/_font_'
export * from '@konghayao/_font_';
}

declare module '*.otf' {
export * from '@konghayao/_font_'
}
export * from '@konghayao/_font_';
}
declare module '*.ttf?subsets' {
export * from '@konghayao/_font_';
}

declare module '*.otf?subsets' {
export * from '@konghayao/_font_';
}
40 changes: 29 additions & 11 deletions packages/vite/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,36 @@
import { InputTemplate, fontSplit } from '@konghayao/cn-font-split';
import { InputTemplate, Subsets, fontSplit } from '@konghayao/cn-font-split';
import path from 'path';
import fs from 'fs';

function getFileName(id: string) {
return path.basename(id).replace(/\./g, '_');
}
function chunk(arr?: number[], size = 500) {
if (arr) {
let result = [];
for (let i = 0; i < arr.length; i += size) {
result.push(arr.slice(i, i + size));
}

return result;
} else {
return;
}
}

export type BundlePluginConfig = Partial<
InputTemplate & {
cacheDir?: string;
server?: boolean;
}
>;

export class BundlePlugin {
constructor(
public config: Partial<
InputTemplate & {
cacheDir?: string;
server?: boolean;
}
> = {},
) { }
public config: BundlePluginConfig = {},
public subsets: number[][] | undefined = undefined,
) {}

getResolvedPath(p: string) {
return path.resolve(this.config.cacheDir!, getFileName(p));
}
Expand All @@ -39,9 +55,9 @@ export class BundlePlugin {
let stat: boolean;
try {
await fs.promises.access(resolvedPath);
stat = true
stat = true;
} catch (e) {
stat = false
stat = false;
}
if (!stat && this.config.server !== false) {
console.log('vite-plugin-font | font pre-building');
Expand All @@ -50,7 +66,9 @@ export class BundlePlugin {
FontPath: p,
destFold: resolvedPath,
reporter: true,
log() { },
autoChunk: !this.subsets,
subsets: chunk(this.subsets?.flat()),
log() {},
}).catch((e) => {
console.error(e);
});
Expand Down
65 changes: 65 additions & 0 deletions packages/vite/src/subset/SubsetBundlePlugin.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import { BundlePlugin, BundlePluginConfig } from '../index.js';
import { glob } from 'glob';
import fs from 'fs';
import crypto from 'node:crypto';
export interface SubsetBundlePluginConfig extends BundlePluginConfig {
scanFiles: string | string[];
ignore?: string | string[];
whiteList?: string | string[];
}
export class SubsetBundlePlugin extends BundlePlugin {
subsetConfig: SubsetBundlePluginConfig;
constructor(config: SubsetBundlePluginConfig) {
super(config);
this.subsetConfig = config;
}

usedSubsets = new Set<number>();
async createSubsets() {
this.getWhiteListSubsets();
await this.getScanFiles();
const subsetsArr = [...this.usedSubsets].sort((a, b) => a - b);
this.subsets = [subsetsArr];
return crypto
.createHash('md5')
.update(String.fromCharCode(...subsetsArr))
.digest('hex');
}
async getScanFiles() {
const files = await glob(this.subsetConfig.scanFiles, {
absolute: true,
nodir: true,
ignore: this.subsetConfig.ignore ?? ['node_modules/**'],
});
return Promise.all(
files.map((i) => {
return new Promise((res, rej) => {
const stream = fs.createReadStream(i, {
encoding: 'utf8',
});
stream.on('data', (i: string) => {
i.split('').forEach((char) =>
this.usedSubsets.add(char.charCodeAt(0)),
);
});
stream.on('end', () => {
res(null);
});
stream.on('error', (err) => {
rej(err);
});
});
}),
);
}
getWhiteListSubsets() {
let whiteList = this.subsetConfig.whiteList ?? [];
if (!(whiteList instanceof Array)) {
whiteList = [whiteList];
}
const set = this.usedSubsets;
whiteList.forEach((str) =>
str.split('').forEach((char) => set.add(char.charCodeAt(0))),
);
}
}
32 changes: 32 additions & 0 deletions packages/vite/src/subset/vite.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import type { Plugin } from 'vite';
import path from 'path';

import {
SubsetBundlePlugin,
SubsetBundlePluginConfig,
} from './SubsetBundlePlugin.js';
export default function split(config: SubsetBundlePluginConfig): Plugin {
const plugin = new SubsetBundlePlugin(config);
return <Plugin>{
name: 'vite-plugin-font-subsets',
enforce: 'pre',

async configResolved(c) {
const hash = await plugin.createSubsets();
plugin.config.cacheDir = path.resolve(
config.cacheDir ?? path.resolve(c.cacheDir, './.font/'),
hash,
);
console.log(
'vite-plugin-font | cache dir | ' + plugin.config.cacheDir,
);
},
async load(id, options) {
if (['.otf?subsets', '.ttf?subsets'].some((i) => id.endsWith(i))) {
id = id.split('?')[0];
await plugin.createBundle(id);
return plugin.createSourceCode(id);
}
},
};
}
2 changes: 1 addition & 1 deletion packages/vite/src/vite.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export default function split(
plugin.config.cacheDir =
config.cacheDir ?? path.resolve(c.cacheDir, './.font/');
console.log(
'cn-font-split | 字体构建缓存地址 | ' + plugin.config.cacheDir,
'vite-plugin-font | cache dir | ' + plugin.config.cacheDir,
);
},
async load(id, options) {
Expand Down
4 changes: 2 additions & 2 deletions packages/vite/vite.config.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { defineConfig } from 'vite';
import Plugin from './dist/vite.js';
import Plugin from './src/vite';
export default defineConfig({
plugins: [Plugin()],
plugins: [Plugin({})],
build: {
outDir: 'build',
},
Expand Down
Loading

0 comments on commit aca88c6

Please sign in to comment.