Skip to content

Commit fda7784

Browse files
committed
feat: 🚀 新增打包功能,优化打包策略
1 parent 6d5c6f3 commit fda7784

File tree

36 files changed

+333
-210
lines changed

36 files changed

+333
-210
lines changed

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
- JS 支持修改 themeConfig
1111
- 构建测试、部署测试、线上效果测试
1212
- 项目发布 NPM 库
13+
- 版本号打包后自动更新
1314

1415
## 使用
1516

build/helper/excludeFiles.ts

+2-6
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,2 @@
1-
// 基础
2-
const excludes = ['node_modules', 'dist'];
3-
4-
export const excludeFiles = (files: string[]) => {
5-
return files.filter(path => !excludes.some(exclude => path.includes(exclude)));
6-
};
1+
// 打包时需要忽略的目录
2+
export const excludes = ["**/node_modules", "**/dist"];

build/helper/external.ts

+17-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,18 @@
1+
// 打 umd 包时针对 external 外部依赖指定全局变量名称
2+
export const globals = {
3+
vue: "Vue",
4+
vite: "Vite",
5+
vitepress: "VitePress",
6+
"vitepress/theme": "VitePressTheme",
7+
"node:path": "node:path",
8+
"node:fs": "node:fs",
9+
fs: "fs",
10+
"gray-matter": "GrayMatter",
11+
"element-plus": "ElementPlus",
12+
"@element-plus/icons-vue": "ElementPlusIconsVue",
13+
"@giscus/vue": "Giscus",
14+
"@waline/client": "Waline",
15+
};
16+
117
// 指定外部依赖,rollup 不会将这些依赖代码打包进去
2-
export const external = ['vue', 'vitepress', 'vitepress/theme', 'node:path', 'node:fs', 'chalk', 'gray-matter'];
18+
export const external = Object.keys(globals);

build/helper/index.ts

+2-5
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,5 @@ export * from './excludeFiles';
44
export * from './external';
55
export * from './plugin';
66

7-
export const target = 'es2018';
8-
9-
export const PKG_NAME = 'vitepress-theme-teeker';
10-
11-
export const PKG_CAMEL_CASE_NAME = 'teeker';
7+
export const target = 'es2020';
8+
export const PKG_CAMEL_CASE_NAME = 'Teeker';

build/helper/path.ts

+15-14
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,30 @@
1-
import { resolve } from 'path';
1+
import { resolve } from "path";
2+
3+
export const PKG_NAME = "vitepress-theme-teeker";
24

35
/** 项目根目录 `/` */
4-
export const projRoot = resolve(__dirname, '../../');
6+
export const projRoot = resolve(__dirname, "../../");
57
/** vitepress-theme-teeker 目录 即 `/vitepress-theme-teeker` */
6-
export const tkRoot = resolve(projRoot, 'vitepress-theme-teeker');
8+
export const tkRoot = resolve(projRoot, PKG_NAME);
79

810
/** 组件目录 `/vitepress-theme-teeker/components` */
9-
export const compRoot = resolve(tkRoot, 'components');
11+
export const compRoot = resolve(tkRoot, "components");
1012

1113
/** Docs */
12-
export const docsDirName = 'docs';
14+
export const docsDirName = "docs";
1315
export const docRoot = resolve(projRoot, docsDirName);
14-
export const vpRoot = resolve(docRoot, '.vitepress');
16+
export const vpRoot = resolve(docRoot, ".vitepress");
1517

1618
/** `/dist` */
17-
export const buildOutput = resolve(projRoot, 'dist');
19+
export const buildOutput = resolve(projRoot, "dist");
1820
/** `/dist/vitepress-theme-teeker` */
19-
export const tkOutput = resolve(buildOutput, 'vitepress-theme-teeker');
21+
export const tkOutput = resolve(buildOutput, PKG_NAME);
2022
/** /dist/types */
21-
export const tsOutput = resolve(buildOutput, 'types');
23+
export const tsOutput = resolve(buildOutput, "types");
2224

23-
export const tkPackage = resolve(tkRoot, 'package.json');
24-
export const projPackage = resolve(projRoot, 'package.json');
25-
export const docPackage = resolve(docRoot, 'package.json');
25+
export const tkPackage = resolve(tkRoot, "package.json");
26+
export const projPackage = resolve(projRoot, "package.json");
27+
export const docPackage = resolve(docRoot, "package.json");
2628

2729
/** /tsconfig.web.json */
28-
export const webTsConfig = resolve(projRoot, 'tsconfig.web.json');
29-
30+
export const webTsConfig = resolve(projRoot, "tsconfig.web.json");

build/helper/plugin.ts

+28-5
Original file line numberDiff line numberDiff line change
@@ -6,19 +6,25 @@ import autoprefixer from "autoprefixer";
66
import { nodeResolve } from "@rollup/plugin-node-resolve";
77
import { target } from "../helper";
88
import vuePlugin from "@vitejs/plugin-vue";
9-
// import vue from "rollup-plugin-vue";
9+
import url from "@rollup/plugin-url";
10+
import cssnano from "cssnano";
11+
import type { Plugin } from "rollup";
1012

1113
// rollup 插件。rollup 本身只支持原生 JavaScript 文件打包,如果项目包含 vue、json 等非原生 JavaScript 文件,则利用插件来支持打包
1214
export const plugins = [
15+
vitepressThemeTeekerClearConsole(),
1316
vuePlugin({ isProduction: true }),
14-
// vue({}),
1517
json(),
1618
// 解析和处理 Node.js 风格的模块导入语句(如 `import something from 'my-package'`),因为 Rollup 本身默认仅支持 ES 模块导入(即通过相对或绝对路径导入本地文件)
17-
nodeResolve({ extensions: [".mjs", ".js", ".json", ".ts"] }),
19+
nodeResolve({
20+
extensions: [".mjs", ".js", ".json", ".ts"],
21+
}),
1822
commonjs(),
23+
url({ include: ["**/*.png", "**/*.jpg"] }),
1924
postcss({
20-
extract: true,
21-
plugins: [autoprefixer()],
25+
namedExports: true,
26+
extract: "index.css",
27+
plugins: [autoprefixer(), cssnano()],
2228
}),
2329
// 利用 esbuild 打包,能提高打包速度
2430
esbuild({
@@ -30,3 +36,20 @@ export const plugins = [
3036
},
3137
}),
3238
];
39+
40+
/**
41+
* 清除 console.log
42+
*/
43+
export function vitepressThemeTeekerClearConsole(): Plugin {
44+
const reg = /console\.log\([^)]*\);?\n?/g;
45+
return {
46+
name: "vitepress-theme-teeker-clear-console-plugin",
47+
transform(code, id) {
48+
if (id.endsWith(".ts") || id.endsWith(".vue")) {
49+
const transformedCode = code.replace(reg, "");
50+
return transformedCode;
51+
}
52+
return code;
53+
},
54+
};
55+
}

build/helper/rollup.ts

+10-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,14 @@
1-
import { OutputOptions, RollupBuild } from 'rollup';
2-
1+
import { OutputOptions, RollupBuild } from "rollup";
32

43
export function writeBundles(bundle: RollupBuild, options: OutputOptions[]) {
54
return Promise.all(options.map(option => bundle.write(option)));
65
}
6+
7+
export function writeBundlesFn(getBundleFn: (format: "esm" | "cjs") => Promise<RollupBuild>, options: OutputOptions[]) {
8+
return Promise.all(
9+
options.map(async option => {
10+
const bundle = await getBundleFn(option.format as "esm" | "cjs");
11+
await bundle.write(option);
12+
})
13+
);
14+
}

build/index.ts

+10-4
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { copyFile, readFile, writeFile } from "fs/promises";
33
import { copy } from "fs-extra";
44
import { resolve } from "path";
55
import { tkPackage, tkOutput, projRoot, buildOutput } from "./helper";
6-
import chalk from "chalk";
6+
import picocolors from "picocolors";
77

88
/**
99
* 复制 .d.ts 文件到指定目录
@@ -39,15 +39,21 @@ const updateVersion = async () => {
3939
tkOutputPkgInfo.version = tkPackageInfo.version;
4040

4141
await writeFile(tkOutputPkg, JSON.stringify(tkOutputPkgInfo, null, 2) + "\n");
42+
43+
// const versionFile = resolve(tkOutput, "es/version.mjs");
44+
// const versionContent = await readFile(versionFile, "utf-8");
45+
// const newVersion = versionContent.replace("1.0.0", tkPackageInfo.version);
46+
47+
// await writeFile(versionFile, JSON.stringify(newVersion, null, 2) + "\n");
4248
};
4349

4450
Promise.all(tasks).then(async () => {
4551
await copyTypesDefinitions();
46-
console.log(chalk.green("Successfully copied definition file"));
52+
console.log(picocolors.green("Successfully copied definition file"));
4753

4854
await copyFiles();
49-
console.log(chalk.green("Successfully copied package.json and README.md"));
55+
console.log(picocolors.green("Successfully copied package.json and README.md"));
5056

5157
await updateVersion();
52-
console.log(chalk.green("Successfully updated version"));
58+
console.log(picocolors.green("Successfully updated version"));
5359
});

build/package.json

+4-2
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,18 @@
1515
"@rollup/plugin-commonjs": "^28.0.2",
1616
"@rollup/plugin-json": "^6.1.0",
1717
"@rollup/plugin-node-resolve": "^16.0.0",
18+
"@rollup/plugin-url": "^8.0.2",
19+
"@types/fs-extra": "^11.0.4",
1820
"@vitejs/plugin-vue": "^5.2.1",
1921
"autoprefixer": "^10.4.20",
20-
"chalk": "^5.4.1",
22+
"cssnano": "^7.0.6",
2123
"esbuild": "^0.24.2",
2224
"fast-glob": "^3.3.3",
2325
"fs-extra": "^11.2.0",
26+
"picocolors": "^1.1.1",
2427
"rollup": "^4.30.1",
2528
"rollup-plugin-esbuild": "^6.1.1",
2629
"rollup-plugin-postcss": "^4.0.2",
27-
"rollup-plugin-vue": "^6.0.0",
2830
"unbuild": "^3.2.0",
2931
"vite-plugin-dts": "^4.5.0"
3032
}

build/tasks/full-bundle.ts

+19-27
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
import { resolve } from 'path';
2-
import { readFileSync } from 'fs';
3-
import { rollup } from 'rollup';
4-
import { minify as minifyPlugin } from 'rollup-plugin-esbuild';
5-
import chalk from 'chalk';
1+
import { resolve } from "path";
2+
import { readFileSync } from "fs";
3+
import { rollup } from "rollup";
4+
import { minify as minifyPlugin } from "rollup-plugin-esbuild";
5+
import picocolors from "picocolors";
66
import {
77
projPackage,
88
target,
@@ -13,9 +13,10 @@ import {
1313
PKG_CAMEL_CASE_NAME,
1414
plugins,
1515
external,
16-
} from '../helper';
16+
globals,
17+
} from "../helper";
1718

18-
const pkg = JSON.parse(readFileSync(projPackage, 'utf-8'));
19+
const pkg = JSON.parse(readFileSync(projPackage, "utf-8"));
1920

2021
// 在 Rollup 中,banner 用于在打包生成的输出文件顶部添加一段文本。这段文本可以是版权声明、警告信息、版本号等任何你希望在文件开头显示的内容。
2122
const banner = `/*! ${PKG_NAME} v${pkg.version} */\n`;
@@ -30,48 +31,39 @@ const buildAll = async (minify?: boolean) => {
3031
);
3132
}
3233

33-
console.log(chalk.cyan(`Starting build ${minify ? 'compressed' : ''} full-bundle`));
34+
console.log(picocolors.cyan(`Starting build ${minify ? "compressed " : ""}full-bundle`));
3435

3536
// 配置详情地址:https://cn.rollupjs.org/configuration-options/
3637
const bundle = await rollup({
37-
input: resolve(tkRoot, 'index.ts'), // 打包入口文件
38+
input: resolve(tkRoot, "src/index.ts"), // 打包入口文件
3839
plugins,
3940
external, // 指定外部依赖,Rollup 不会将这些依赖代码打包进去
4041
treeshake: true, // 允许移除未使用的导出和代码
4142
});
4243

4344
await writeBundles(bundle, [
4445
{
45-
format: 'umd',
46-
file: resolve(tkOutput, `index${minify ? '.min' : ''}.js`), // 打包后的文件路径
47-
exports: 'named',
46+
format: "umd",
47+
file: resolve(tkOutput, `index${minify ? ".min" : ""}.js`), // 打包后的文件路径
48+
exports: "named",
4849
name: PKG_CAMEL_CASE_NAME, // 全局变量名称,通过这个变量名来访问打包后的入口文件,如浏览器端如果 window.${PKG_CAMEL_CASE_NAME} 访问
4950
sourcemap: false,
5051
banner,
5152
// 指定外部依赖: 当你将某些模块标记为 external 时,Rollup 不会将它们打包进最终的输出文件中。为了确保这些模块在运行时能够被正确引用,通过 globals 来指定这些模块对应的全局变量名称
52-
globals: {
53-
vue: 'Vue',
54-
'node:path': 'node:path',
55-
'node:fs': 'node:fs',
56-
fs: 'fs',
57-
chalk: 'Chalk',
58-
'gray-matter': 'GrayMatter',
59-
vitepress: 'VitePress',
60-
'vitepress/theme': 'VitePressTheme',
61-
},
53+
globals,
6254
},
6355
{
64-
format: 'esm',
65-
file: resolve(tkOutput, `index${minify ? '.min' : ''}.js`),
56+
format: "esm",
57+
file: resolve(tkOutput, `index${minify ? ".min" : ""}.js`),
6658
sourcemap: false,
6759
},
6860
]);
6961

7062
const msg = minify
71-
? 'Successfully build compressed full-bundle For umd and esm'
72-
: 'Successfully build full-bundle For umd and esm';
63+
? "Successfully build compressed full-bundle For umd and esm"
64+
: "Successfully build full-bundle For umd and esm";
7365

74-
console.log(chalk.green(msg));
66+
console.log(picocolors.green(msg));
7567
};
7668

7769
export default [buildAll(false), buildAll(true)];

0 commit comments

Comments
 (0)