@@ -99,7 +99,7 @@ pnpm i clsx -D
9999
100100代码我就不列出来了,大家可以自行编写,或者去仓库看也可以,就是一个简单的示例组件,编写完成后,目录结构如下
101101
102- ![ image] ( https://img. jsonq.top/blog /2025/2 /25/1740465671795-5ag1kxb7.png )
102+ ![ image] ( https://jsonq.top/cdn-static /2025/02 /25/1740465671795-5ag1kxb7.png )
103103
104104- 由于样式后续要做按需导入,所以必须确保每个组件的样式 style 有一个导出的 index.(ts|js) 文件和 index.less 文件
105105- index.(ts|js) 的内容就是 ` @import xxx.less `
@@ -280,7 +280,7 @@ pnpm i rimraf -D -w
280280
281281然后执行命令 ` pnpm build ` ,就能在 lib 目录下看到 commonjs 的代码了,且诸多 helper 方法已被抽离至 ` @babel/runtime ` 中
282282
283- ![ image] ( https://img. jsonq.top/blog /2025/2 /25/1740465672018-rqpzh6mq.png )
283+ ![ image] ( https://jsonq.top/cdn-static /2025/02 /25/1740465672018-rqpzh6mq.png )
284284
285285## 导出 ESM 代码
286286
@@ -349,7 +349,7 @@ const build = gulp.parallel(gulp.series(compileCJS, compileESM));
349349
350350执行 ` pnpm build ` ,观察 es 目录下的编译结果,都是 ` import ` 的 esm 写法
351351
352- ![ image] ( https://img. jsonq.top/blog /2025/2 /25/1740465672207-ut65dlpr.png )
352+ ![ image] ( https://jsonq.top/cdn-static /2025/02 /25/1740465672207-ut65dlpr.png )
353353
354354## Less 样式处理
355355
@@ -369,7 +369,7 @@ const build = gulp.parallel(gulp.series(compileCJS, compileESM));
369369
370370这里就举例国内采用同样技术的组件库:[ antd 4.x] ( https://github.com/ant-design/ant-design/tree/4.x-stable ) 、[ arco design] ( https://github.com/arco-design/arco-design ) 、[ tdesign] ( https://github.com/Tencent/tdesign-react ) ,可以参考一下他们的打包后的结构目录
371371
372- ![ image] ( https://img. jsonq.top/blog /2025/2 /25/1740465672432-w93mhxcl.png )
372+ ![ image] ( https://jsonq.top/cdn-static /2025/02 /25/1740465672432-w93mhxcl.png )
373373
374374可以看到以上组件库的样式结构基本都一样(tdesign 直接使用 ` cssvar ` ,但是对外提供了 less 能力),提供了 ` index.js ` (内部是 less 文件的导入)、` css.js ` (内部是 css 文件的导入)` index.css ` (内部是合并后的纯 css)以及原样的 less 文件
375375
@@ -403,7 +403,7 @@ const build = gulp.parallel(gulp.series(compileCJS, compileESM), copyLess);
403403
404404可以看到 less 样式已经按照原来的结构 copy 到 es 和 lib 包中,然后就是生成 css 的步骤。
405405
406- ![ image] ( https://img. jsonq.top/blog /2025/2 /25/1740465672606-2bccrdfz.png )
406+ ![ image] ( https://jsonq.top/cdn-static /2025/02 /25/1740465672606-2bccrdfz.png )
407407
408408### less 编译成 css
409409
@@ -435,7 +435,7 @@ const build = gulp.parallel(gulp.series(compileCJS, compileESM), copyLess, less2
435435
436436执行 ` pnpm build ` ,检查打包文件,如图所示就是成功的。
437437
438- ![ image] ( https://img. jsonq.top/blog /2025/2 /25/1740465672781-6zg13c0t.png )
438+ ![ image] ( https://jsonq.top/cdn-static /2025/02 /25/1740465672781-6zg13c0t.png )
439439
440440这里没有对 css 进行压缩,esm 和 lib 会被用户以 npm 方式使用,用户打包时,自然会对 css 进行压缩。
441441
@@ -474,7 +474,7 @@ const build = gulp.parallel(gulp.series(compileCJS, compileESM), copyLess, less2
474474
475475功能实现参考 [ antd-tools] ( https://github.com/ant-design/antd-tools ) ,由于 antd5 现在不使用 less 了,就直接找到之前的 commit 把代码贴出来了,如下图所示
476476
477- ![ image] ( https://img. jsonq.top/blog /2025/2 /25/1740465672947-51pmv6ad.png )
477+ ![ image] ( https://jsonq.top/cdn-static /2025/02 /25/1740465672947-51pmv6ad.png )
478478
479479这段代码做的就是匹配到 ` style/index.js ` 时,生成 ` style/css.js ` ,并通过正则将文件内容中引入的 less 文件后缀改成 css。
480480
@@ -537,7 +537,7 @@ function cssInjection(content) {
537537
538538执行 ` pnpm build ` ,即可看到 ` css.js ` 文件
539539
540- ![ image] ( https://img. jsonq.top/blog /2025/2 /25/1740465673066-o1sbcgs5.png )
540+ ![ image] ( https://jsonq.top/cdn-static /2025/02 /25/1740465673066-o1sbcgs5.png )
541541
542542> 其实这一部分很多可以优化的地方,做的更细致一点,大家在看懂之后可以自行尝试优化,比如 ` token.css ` 并不存在(` token.less ` 未被编译),可以去掉,再比如可以把 less 变量编译 cssvar,` css.js ` 可以再额外引入 css 变量,就可以做到动态换肤功能。
543543
@@ -593,7 +593,7 @@ cssinjs 的库都不需要这个,因为 cssinjs 只有 js,天然支持 `tree
593593
594594其实 ` exports ` 是用来替代 ` @babel/plugin-transform-runtime ` 的 ` useESModules ` 的(对导出这块我也不是很熟,同样是查资料和摸索出来的)
595595
596- ![ image] ( https://img. jsonq.top/blog /2025/2 /25/1740465673182-ihgkdchv.png )
596+ ![ image] ( https://jsonq.top/cdn-static /2025/02 /25/1740465673182-ihgkdchv.png )
597597
598598而后边又添加了 ` ./es/*": "./es/* ` 等的指向,是因为我在使用按需加载的过程中发现插件无法从 ` ./es ` 中读取文件,找不到文件路径,而且编辑器无法给出路径提示(看样子确实是没有指定到文件下),所以才有了这一系列的指向,大家可以去掉之后自行尝试一下。
599599
@@ -645,7 +645,7 @@ storybook 分两个运行界面,一个是 vite + react 默认的模板页面
645645
646646在 ` App.tsx ` 中导入组件
647647
648- ![ image] ( https://img. jsonq.top/blog /2025/2 /25/1740465673340-xbx2ifpr.png )
648+ ![ image] ( https://jsonq.top/cdn-static /2025/02 /25/1740465673340-xbx2ifpr.png )
649649
650650运行 ` pnpm dev ` ,打开即可看到一个很丑的按钮 button,因为没有样式,接下来我们做样式的按需导入
651651
@@ -688,7 +688,7 @@ export default defineConfig({
688688
689689此时一个漂亮的按钮就成功出来了
690690
691- 
691+ 
692692
693693> 这么看来在项目结构搭建时可以把 ` storybook` 作为根目录作为项目共享的配置,这样可以直接在 ` components` 文件夹下写 story 文档,结构上更方便查看
694694
@@ -754,7 +754,7 @@ export const ButtonSize: Story = {
754754
755755执行 ` pnpm storybook` ,运行 storybook 文档
756756
757- 
757+ 
758758
759759样式的按需加载也被 storybook 文档享受到了,不需要单独导入 css。
760760
@@ -891,7 +891,7 @@ module.exports = merge(prodConfig, commonConfig);
891891
892892执行 ` pnpm build: dist` ,就可以看到生成了 ` dist` 文件夹
893893
894- 
894+ 
895895
896896### 细节优化
897897
@@ -966,7 +966,7 @@ function less2css() {
966966
967967执行 ` pnpm build` ,如图所示,就大功告成了
968968
969- 
969+ 
970970
971971> 其实 webpack 打包 dist 这块不用拆分出 ` dev` 和 ` prod` 两个文件,可以将配置项作为一个函数,通过传参判断构建的产物类型,作为构建脚本执行会更合适。
972972
@@ -1007,7 +1007,7 @@ function less2css() {
10071007< / html>
10081008` ` `
10091009
1010- 
1010+ 
10111011
10121012组件库的打包到此结束!同时期待阅读这篇文章的你有更深入的优化
10131013
0 commit comments